如何在Win32编程中实现多线程同步?
在Win32编程中,多线程同步是确保多个线程能够正确、有序地访问共享资源的关键。Win32 API提供了多种同步机制,如临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)和事件(Event)。以下是一些常用的同步机制及其示例。
1. 临界区(Critical Section)
临界区用于保护共享资源,确保同一时间只有一个线程可以访问该资源。
#include <windows.h>
#include <iostream>
CRITICAL_SECTION cs;
int sharedData = 0;
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
for (int i = 0; i < 1000; ++i)
{
EnterCriticalSection(&cs);
sharedData++;
DWORD threadId = GetCurrentThreadId();
std::cout << "Thread ID: " << threadId << std::endl;
LeaveCriticalSection(&cs);
}
return 0;
}
int main() {
InitializeCriticalSection(&cs);
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread1);
CloseHandle(hThread2);
DeleteCriticalSection(&cs);
std::cout << "Shared Data: " << sharedData << std::endl;
return 0;
}
代码说明
上述代码中创建两个线程,对全局变量sharedData进行自加1000次的操作。
-
InitializeCriticalSection:初始化临界区。
-
EnterCriticalSection:进入临界区。
-
LeaveCriticalSection:离开临界区。
-
DeleteCriticalSection:删除临界区。
代码运行结果:
2. 互斥量(Mutex)
互斥量用于确保同一时间只有一个线程可以访问共享资源。
#include <windows.h>
#include <iostream>
HANDLE hMutex;
int sharedData = 0;
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
for (int i = 0; i < 1000; ++i) {
WaitForSingleObject(hMutex, INFINITE);
sharedData++;
ReleaseMutex(hMutex);
}
return 0;
}
int main() {
hMutex = CreateMutex(NULL, FALSE, NULL);
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hMutex);
std::cout << "Shared Data: " << sharedData << std::endl;
return 0;
}
代码说明
-
CreateMutex:创建互斥量。
-
WaitForSingleObject:等待互斥量。
-
ReleaseMutex:释放互斥量。
-
CloseHandle:关闭互斥量句柄。
3. 信号量(Semaphore)
信号量用于控制对共享资源的访问数量。
#include <windows.h>
#include <iostream>
HANDLE hSemaphore;
int sharedData = 0;
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
for (int i = 0; i < 1000; ++i) {
WaitForSingleObject(hSemaphore, INFINITE);
sharedData++;
ReleaseSemaphore(hSemaphore, 1, NULL);
}
return 0;
}
int main() {
hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hSemaphore);
std::cout << "Shared Data: " << sharedData << std::endl;
return 0;
}
代码说明
-
CreateSemaphore:创建信号量。
-
WaitForSingleObject:等待信号量。
-
ReleaseSemaphore:释放信号量。
-
CloseHandle:关闭信号量句柄。
4. 事件(Event)
事件用于线程间的通信和同步。
#include <windows.h>
#include <iostream>
HANDLE hEvent;
int sharedData = 0;
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
for (int i = 0; i < 1000; ++i) {
WaitForSingleObject(hEvent, INFINITE);
sharedData++;
SetEvent(hEvent);
}
return 0;
}
int main() {
hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hEvent);
std::cout << "Shared Data: " << sharedData << std::endl;
return 0;
}
代码说明
-
CreateEvent:创建事件。
-
WaitForSingleObject:等待事件。
-
SetEvent:设置事件。
-
CloseHandle:关闭事件句柄。
总结
在Win32编程中,多线程同步可以通过多种机制实现,包括临界区、互斥量、信号量和事件。每种机制都有其适用的场景:
-
临界区:适用于同一进程内的线程同步。
-
互斥量:适用于跨进程的线程同步。
-
信号量:适用于控制对多个资源的访问。
-
事件:适用于线程间的通信和同步。
通过合理选择和使用这些同步机制,可以确保多线程程序的正确性和稳定性。
句柄。