1、临界区
用CRITICAL_SECTION结构对象保护共享资源。
用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。
所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用。
如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占。
#include <iostream>
#include <Windows.h>
#include <vector>
std::vector<int> a(5,0);
CRITICAL_SECTION g_Critical;
DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
InitializeCriticalSection(&g_Critical);
CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
system("pause");
return 0;
}
DWORD WINAPI ThreadProc1(PVOID pParam)
{//给vector赋值
EnterCriticalSection(&g_Critical);
a = { 1,2,3,4,5 };
LeaveCriticalSection(&g_Critical);
return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{//打印vector的值
EnterCriticalSection(&g_Critical);
for (auto i = a.begin() ; i != a.end() ; i++)
{
std::cout << *i;
Sleep(10);
}
LeaveCriticalSection(&g_Critical);
return 0;
}
2、事件
HANDLE CreateEventA( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName );
第二个参数如果为TRUE,该对象需要使用ResetEvent函数将事件状态设置为非信号状态。如果设置为FALSE,当一个线程等待到事件信号后系统会自动将事件状态复原为无信号状态。
第三个参数表示初始状态,为TRUE则有信号,为FALSE则无信号
第四个参数是名字。
可以使用WaitForSingleObject进行等待
#include <Windows.h>
#include <iostream>
int x = 0;
HANDLE g_hEvent;
DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
g_hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("Test"));
CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
system("pause");
return 0;
}
DWORD WINAPI ThreadProc1(PVOID pParam)
{
DWORD dwReturn = WaitForSingleObject(g_hEvent, INFINITE);
if (dwReturn == WAIT_OBJECT_0)
{
x++;
std::cout << "this is thread1,x = ";
std::cout << x << std::endl;
ResetEvent(g_hEvent);
}
return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{
//Sleep(10);
x++;
std::cout << "this is thread2,x = ";
std::cout << x << std::endl;
SetEvent(g_hEvent);
return 0;
}
3、信号量
主要是两个函数
创建信号量:
CreateSemaphore(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes //安全属性
_In_ LONG lInitialCount, //初始资源数
_In_ LONG lMaximumCount, //最大资源数
_In_opt_ LPCTSTR lpName //名字
);
释放信号量,会增加信号量计数
BOOL WINAPI ReleaseSemaphore(
HANDLE hSemaphore, //信号量句柄
LONG lReleaseCount, //当前资源数增加数量
LPLONG lpPreviousCount //增加前的数量
);
例子:
#include <Windows.h>
#include <iostream>
int x = 0;
HANDLE g_Semaphore;
DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
g_Semaphore = CreateSemaphore(NULL, 1, 2, TEXT("test"));
CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
Sleep(100);
system("pause");
return 0;
}
DWORD WINAPI ThreadProc1(PVOID pParam)
{
while (x < 10)
{
DWORD dwReturn = WaitForSingleObject(g_Semaphore, INFINITE);
if (dwReturn == WAIT_OBJECT_0)
{
x++;
std::cout << "this is thread1,x = ";
std::cout << x << std::endl;
long count;
ReleaseSemaphore(g_Semaphore, 1, &count);
}
}
return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{
//Sleep(10);
while (x < 10)
{
DWORD dwReturn = WaitForSingleObject(g_Semaphore, INFINITE);
if (dwReturn == WAIT_OBJECT_0)
{
x++;
std::cout << "this is thread2,x = ";
std::cout << x << std::endl;
long count;
ReleaseSemaphore(g_Semaphore, 1, &count);
}
}
return 0;
}
4、互斥量
#include <Windows.h>
#include <iostream>
int x = 0;
HANDLE g_Mutex;
DWORD WINAPI ThreadProc1(PVOID pParam);
DWORD WINAPI ThreadProc2(PVOID pParam);
int main()
{
g_Mutex = CreateMutex(NULL, FALSE, TEXT("test"));
CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
Sleep(200);
system("pause");
return 0;
}
DWORD WINAPI ThreadProc1(PVOID pParam)
{
while (x < 10)
{
DWORD dwReturn = WaitForSingleObject(g_Mutex, INFINITE);
if (dwReturn == WAIT_OBJECT_0)
{
x++;
std::cout << "this is thread1,x = ";
std::cout << x << std::endl;
Sleep(10);
ReleaseMutex(g_Mutex);
}
}
return 0;
}
DWORD WINAPI ThreadProc2(PVOID pParam)
{
//Sleep(10);
while (x < 10)
{
DWORD dwReturn = WaitForSingleObject(g_Mutex, INFINITE);
if (dwReturn == WAIT_OBJECT_0)
{
x++;
std::cout << "this is thread2,x = ";
std::cout << x << std::endl;
Sleep(10);
ReleaseMutex(g_Mutex);
}
}
return 0;
}