Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Tabla de contenido
En un entorno de subprocesos múltiples, cuando varios subprocesos acceden o modifican los mismos datos al mismo tiempo, el resultado final es el tiempo de ejecución del subproceso.
Si no existe un mecanismo de sincronización, se producirán condiciones de carrera, lo que puede provocar datos inexactos o excepciones del programa.
- #include <iostream>
- #include <windows.h>
-
- DWORD g_Num = 0;
-
- DWORD WINAPI WorkThread(LPVOID lp)
- {
- for (size_t i = 0; i < 10000000; i++)
- {
- //g_Num++;
- __asm LOCK INC [g_Num]
- }
- return 0;
- }
-
- int main()
- {
- HANDLE hThread[2] = { 0 };
- hThread[0] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
- hThread[1] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
- WaitForMultipleObjects(2, hThread, TRUE, -1);
- std::cout << g_Num << std::endl;
-
- return 0;
- }
- #include <iostream>
- #include <windows.h>
-
- DWORD g_Num = 0;
- CRITICAL_SECTION cs = { 0 };
-
- DWORD WINAPI WorkThread(LPVOID lp)
- {
- for (size_t i = 0; i < 1000000; i++)
- {
- // 进入临界区
- EnterCriticalSection(&cs);
-
- // TODO
- g_Num++;
-
- // 退出临界区
- LeaveCriticalSection(&cs);
- }
- return 0;
- }
-
- int main()
- {
-
- HANDLE hThread[2] = { 0 };
- // 初始临界区
- InitializeCriticalSection(&cs);
-
- hThread[0] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
- hThread[1] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
-
- WaitForMultipleObjects(2, hThread, TRUE, -1);
-
- std::cout << g_Num << std::endl;
-
- // 清理临界区
- DeleteCriticalSection(&cs);
-
- return 0;
- }
Mutex (Mutex) se utiliza para evitar que varios subprocesos accedan o modifiquen recursos compartidos al mismo tiempo.
Solo un subproceso puede poseer el mutex al mismo tiempo. Si un subproceso toma posesión del mutex, otros subprocesos que soliciten el mutex se bloquearán hasta que se libere el permiso del mutex.
Crear un mutex - CreateMutex
Solicitar exclusión mutua: WaitForSingleObject
Liberar el mutex - ReleaseMutex
- #include <iostream>
- #include <windows.h>
-
- HANDLE hMutex = 0;
- DWORD g_Num = 0;
-
- DWORD WINAPI WorkThread(LPVOID lp)
- {
- for (size_t i = 0; i < 100000; i++)
- {
- WaitForSingleObject(hMutex, INFINITE);
- g_Num++;
- ReleaseMutex(hMutex);
- }
-
- return 0;
- }
-
- int main()
- {
- hMutex = CreateMutex(NULL, FALSE, NULL);
-
- HANDLE hThread1 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
- HANDLE hThread2 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
-
- WaitForSingleObject(hThread1, INFINITE);
- WaitForSingleObject(hThread2, INFINITE);
-
- CloseHandle(hThread1);
- CloseHandle(hThread2);
- CloseHandle(hMutex);
-
- std::cout << g_Num << std::endl;
-
- return 0;
- }
sección crítica
Mecanismo de sincronización de subprocesos para recursos compartidos, las secciones críticas proporcionan acceso mutuamente exclusivo entre subprocesos del mismo proceso.
Cada subproceso debe poder ingresar a la sección crítica antes de acceder a los recursos compartidos y salir de la sección crítica después de completar el acceso para completar la sincronización del subproceso.
exclusión mutua
El mecanismo de sincronización de subprocesos se utiliza para restringir el acceso de varios subprocesos a recursos compartidos al mismo tiempo.
- #include <iostream>
- #include <Windows.h>
-
- int main()
- {
- HANDLE hMutex = CreateMutex(NULL, FALSE, L"0xCC_Mutex");
- if (hMutex == NULL) return 0;
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- MessageBox(NULL, L"禁止多开", L"错误", MB_OKCANCEL);
- return 0;
- }
- std::cout << "Game Start..." << std::endl;
- system("pause");
- CloseHandle(hMutex);
- return 0;
- }
actuación
Las secciones críticas son más rápidas que las exclusiones mutuas dentro de subprocesos del mismo proceso.
Función
Los mutex se pueden sincronizar entre procesos, pero las secciones críticas solo se pueden sincronizar entre subprocesos del mismo proceso.
propiedad
Los mutex tienen estrictos requisitos de propiedad y solo los subprocesos con permisos mutex pueden liberarlos.
- #include <iostream>
- #include <Windows.h>
-
- CRITICAL_SECTION CriticalSection = { 0 };
-
- DWORD WINAPI WorkThread(LPVOID lp)
- {
- EnterCriticalSection(&CriticalSection);
-
- printf("TID -> %d rn", GetCurrentThreadId());
- Sleep(5000);
-
- LeaveCriticalSection(&CriticalSection);
-
- return 0;
- }
-
- int main()
- {
- InitializeCriticalSection(&CriticalSection);
-
- HANDLE hThread1 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
- Sleep(1000);
- TerminateThread(hThread1, 1);
-
- HANDLE hThread2 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);
- WaitForSingleObject(hThread2, INFINITE);
-
- DeleteCriticalSection(&CriticalSection);
-
- return 0;
- }
- #include <iostream>
- #include <Windows.h>
-
- HANDLE hMutex = NULL;
-
- DWORD WINAPI WorkThread1(LPVOID lp)
- {
- WaitForSingleObject(hMutex, INFINITE);
- printf("TID -> %d rn", GetCurrentThreadId());
- Sleep(5000);
- TerminateThread(GetCurrentThread(), -1);
-
- //todo
- return 0;
- }
-
- DWORD WINAPI WorkThread2(LPVOID lp)
- {
- printf("Wait For Thread1 Leavern");
- WaitForSingleObject(hMutex, INFINITE);
- printf("TID -> %d rn", GetCurrentThreadId());
- ReleaseMutex(hMutex);
- return 0;
- }
-
-
- int main()
- {
- hMutex = CreateMutex(NULL, FALSE, NULL);
-
- HANDLE hThread1 = CreateThread(NULL, 0, WorkThread1, NULL, 0, NULL);
- Sleep(1000);
-
- HANDLE hThread2 = CreateThread(NULL, 0, WorkThread2, NULL, 0, NULL);
- WaitForSingleObject(hThread2, INFINITE);
-
- CloseHandle(hMutex);
- CloseHandle(hThread1);
- CloseHandle(hThread2);
-
- return 0;
- }
Un semáforo es un objeto de sincronización que se utiliza para controlar el acceso a recursos compartidos por parte de múltiples subprocesos. Es un contador que representa la cantidad de recursos disponibles. Cuando el valor del semáforo es mayor que 0, indica que hay recursos disponibles; cuando el valor es 0, indica que no hay recursos disponibles.
esperar : Intenta disminuir el valor del semáforo. Si el valor del semáforo es mayor que 0, disminúyalo en 1 y continúe la ejecución. Si el valor del semáforo es 0, el hilo se bloquea hasta que el valor del semáforo sea mayor que 0.
liberado : Aumenta el valor del semáforo. Si hay otros hilos bloqueados esperando este semáforo, uno de ellos se despertará.
Crear semáforo
En sistemas Windows, utilice CreateSemaphore
oCreateSemaphoreEx
La función crea un semáforo.
Espere (Esperar) y suelte (Liberar) el semáforo
La espera de un semáforo generalmente se realiza usando WaitForSingleObject
oWaitForMultipleObjects
función.
Liberar el uso del semáforo ReleaseSemaphore
función.
- #include <iostream>
- #include <Windows.h>
-
- #define MAX_COUNT_SEMAPHORE 3
-
-
- HANDLE g_SemapHore = NULL;
- HANDLE g_hThreadArr[10] = { 0 };
-
- DWORD WINAPI WorkThread(LPVOID lp)
- {
- WaitForSingleObject(g_SemapHore, INFINITE);
-
- for (size_t i = 0; i < 10; i++)
- {
- std::cout << "COUNT -> " << (int)lp << std::endl;
- Sleep(500);
- }
-
- ReleaseSemaphore(g_SemapHore, 1, NULL);
-
- return 0;
- }
-
- int main()
- {
- g_SemapHore = CreateSemaphore(
- NULL, //安全属性
- MAX_COUNT_SEMAPHORE, //初始计数
- MAX_COUNT_SEMAPHORE, //最大计数
- NULL //信号名称
- );
-
- if (g_SemapHore == NULL)
- {
- std::cout << GetLastError() << std::endl;
- return 1;
- }
-
- for (size_t i = 0; i < 10; i++)
- {
- g_hThreadArr[i] = CreateThread(
- NULL,
- 0,
- WorkThread,
- (LPVOID)i,
- 0,
- NULL
- );
- }
-
- WaitForMultipleObjects(10, g_hThreadArr, TRUE, INFINITE);
-
- //closehandle
-
- return 0;
- }
En la programación de Windows, los eventos son un mecanismo de sincronización que se utiliza para enviar señales entre múltiples subprocesos.El objeto del evento puede serreinicio manualoreinicio automático。
Evento de reinicio manual: cuando se establece (señala) un evento, permanecerá en este estado hasta que se reinicie explícitamente. Esto significa que se pueden activar varios subprocesos que esperan el evento antes de que se restablezca el evento.
Evento de reinicio automático: cuando un hilo en espera recibe (señala) un evento, el sistema restablece automáticamente el estado del evento a no señalizado (sin señalizar). Esto significa que sólo se permite activar un hilo a la vez.
Crear evento
Uso de funciones API de WindowsCreateEvent
Se puede crear un objeto de evento.
lpEventAttributes
: Puntero al atributo de seguridad, si está configurado enNULL
, se utiliza la seguridad predeterminada.
bManualReset
: siTRUE
, se crea un evento de reinicio manual; de lo contrario, se crea un evento de reinicio automático.
bInitialState
: siTRUE
, entonces el estado inicial es el estado de la señal si;FALSE
, es un estado de no señalización.
lpName
: El nombre del evento.
Para configurar un evento (establecer el estado del evento al estado de la señal) useSetEvent
función
Para restablecer un evento (establecer el estado del evento en un estado no señalizado) utiliceResetEvent
función
Espere a que el evento espere a que un objeto de evento se convierta en un estado de señal.WaitForSingleObject
función
- #include <iostream>
- #include <Windows.h>
-
- DWORD WINAPI WorkThread(LPVOID lp)
- {
- HANDLE hEvent = *(HANDLE*)lp;
- std::cout << "Thread - " << GetCurrentThreadId() << " Waiting For Event" << std::endl;
- WaitForSingleObject(hEvent, INFINITE);
- std::cout << "Thread - " << GetCurrentThreadId() << " actived" << std::endl;
- return 0;
- }
-
- int main()
- {
- HANDLE hThreads[3] = { 0 };
- HANDLE hEvent = NULL;
-
- hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (hEvent == NULL) return 0;
-
- for (size_t i = 0; i < 3; i++)
- {
- hThreads[i] = CreateThread(NULL, 0, WorkThread, &hEvent, 0, NULL);
- }
-
- Sleep(2000);
- SetEvent(hEvent);
-
- WaitForMultipleObjects(3, hThreads, TRUE, INFINITE);
-
- CloseHandle(hEvent);
-
- return 0;
- }