le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Sommario
In un ambiente multi-thread, quando più thread accedono o modificano gli stessi dati contemporaneamente, il risultato finale è il tempo di esecuzione del thread.
Se non è presente un meccanismo di sincronizzazione, si verificheranno condizioni di competizione che potrebbero portare a dati imprecisi o eccezioni al programma.
- #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) viene utilizzato per impedire a più thread di accedere o modificare contemporaneamente le risorse condivise.
Solo un thread alla volta può possedere il mutex. Se un thread assume la proprietà del mutex, gli altri thread che richiedono il mutex verranno bloccati fino al rilascio dell'autorizzazione mutex.
Crea un mutex - CreateMutex
Richiedi mutex - WaitForSingleObject
Rilascia il 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;
- }
sezione critica
Meccanismo di sincronizzazione dei thread per risorse condivise, le sezioni critiche forniscono accesso mutuamente esclusivo tra thread dello stesso processo.
Ogni thread deve essere in grado di accedere alla sezione critica prima di accedere alle risorse condivise e lasciare la sezione critica una volta completato l'accesso per completare la sincronizzazione dei thread.
mutex
Il meccanismo di sincronizzazione dei thread viene utilizzato per impedire a più thread di accedere contemporaneamente alle risorse condivise.
- #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;
- }
prestazione
Le sezioni critiche sono più veloci dei mutex all'interno dei thread dello stesso processo.
Funzione
I mutex possono essere sincronizzati tra processi, ma le sezioni critiche possono essere sincronizzate solo tra thread nello stesso processo.
proprietà
I mutex hanno severi requisiti di proprietà e solo i thread con autorizzazioni mutex possono rilasciarlo.
- #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 semaforo è un oggetto di sincronizzazione utilizzato per controllare l'accesso alle risorse condivise da più thread. È un contatore che rappresenta la quantità di risorse disponibili. Quando il valore del semaforo è maggiore di 0 indica che le risorse sono disponibili; quando il valore è 0 indica che non ci sono risorse disponibili;
Aspettare : Tenta di diminuire il valore del semaforo. Se il valore del semaforo è maggiore di 0, decrementalo di 1 e continua l'esecuzione. Se il valore del semaforo è 0, il thread si blocca finché il valore del semaforo non diventa maggiore di 0.
liberato : Aumenta il valore del semaforo. Se ci sono altri thread bloccati in attesa di questo semaforo, uno di essi verrà risvegliato.
Crea semaforo
Sui sistemi Windows, utilizzare CreateSemaphore
OCreateSemaphoreEx
La funzione crea un semaforo.
Attendi (Wait) e rilascia (Release) il semaforo
L'attesa al semaforo viene solitamente eseguita utilizzando WaitForSingleObject
OWaitForMultipleObjects
funzione.
Rilascia l'utilizzo del semaforo ReleaseSemaphore
funzione.
- #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;
- }
Nella programmazione Windows, gli eventi sono un meccanismo di sincronizzazione utilizzato per inviare segnali tra più thread.L'oggetto evento può essereripristino manualeOripristino automatico。
Evento Reset Manuale: Quando un evento viene impostato (segnalato), rimarrà in questo stato fino al reset esplicito. Ciò significa che più thread in attesa dell'evento possono essere risvegliati prima che l'evento venga reimpostato.
Evento di ripristino automatico: quando un evento viene ricevuto (segnalato) da un thread in attesa, il sistema reimposta automaticamente lo stato dell'evento su non segnalato (non segnalato). Ciò significa che è consentito risvegliare un solo thread alla volta.
Crea Evento
Utilizzo delle funzioni API di WindowsCreateEvent
È possibile creare un oggetto evento
lpEventAttributes
: puntatore all'attributo di sicurezza, se impostato suNULL
, viene utilizzata la sicurezza predefinita.
bManualReset
: SeTRUE
, viene creato un evento di ripristino manuale, altrimenti viene creato un evento di ripristino automatico.
bInitialState
: SeTRUE
, allora lo stato iniziale è lo stato del segnale seFALSE
, è uno stato di non segnalazione.
lpName
: il nome dell'evento.
Per impostare un evento (impostare lo stato dell'evento sullo stato del segnale) utilizzareSetEvent
funzione
Per ripristinare un evento (impostare lo stato dell'evento su uno stato non segnalato) utilizzareResetEvent
funzione
Attendi che l'evento attenda che un oggetto evento diventi uno stato di segnale.WaitForSingleObject
funzione
- #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;
- }