线程同步
一、CriticalSection(关键代码段)
只能用于同一个进程中的多线程同步,效率高,速度快。它并不是核心对象,不是属于操作系统维护的,而是属于进程维护的。
CRITICAL_SECTION 结构体
主要函数:
//初始化
void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
//进入关键代码段
void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
//离开关键代码段
void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
//销毁关键代码段
void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
代码如下(示例):
#include <iostream>
#include <Windows.h>
using namespace std;
CRITICAL_SECTION g_cs; //关键代码段
DWORD WINAPI ThreadFun1(LPVOID lpParameter);
DWORD WINAPI ThreadFun2(LPVOID lpParameter);
int g_resource = 100;
int main()
{
InitializeCriticalSection(&g_cs); //初始化关键代码段
HANDLE hThread1 = CreateThread(0, 0, ThreadFun1, 0, 0, 0);
HANDLE hThread2 = CreateThread(0, 0, ThreadFun2, 0, 0, 0);
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(1000);
return 0;
}
DWORD __stdcall ThreadFun1(LPVOID lpParameter)
{
while (1)
{
EnterCriticalSection(&g_cs);
if (g_resource <= 0)
{
LeaveCriticalSection(&g_cs);
break;
}
else
{
cout << "ThreadFun1 used :" << g_resource-- << endl;
LeaveCriticalSection(&g_cs);
Sleep(1); //除了等待之外,还会放弃当前的执行权限
}
}
return 0;
}
DWORD __stdcall ThreadFun2(LPVOID lpParameter)
{
//同ThreadFun1
}
二、Mutex(互斥对象)
用法同CriticalSection相似,可用于不同进程之间的同步,也可用于防止同一个程序多次运行
Mutex
HANDLE WINAPI CreateMutex(
In_opt LPSECURITY_ATTRIBUTES lpMutexAttributes,
In BOOL bInitialOwner, //创建该对象的线程是否拥有它
In_opt LPCTSTR lpName //互斥对象的名
);
主要函数:
WaitForSingleObject(); //等待一个对象
//打开互斥对象
HANDLE OpenMutex(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName //名称
);
//结束访问
BOOL ReleaseMutex (HANDLE hMutex);
代码如下(示例):
#include <iostream>
#include <Windows.h>
using namespace std;
HANDLE g_hMutex; //互斥对象
DWORD WINAPI ThreadFun1(LPVOID lpParameter);
DWORD WINAPI ThreadFun2(LPVOID lpParameter);
int g_resource = 100;
int main()
{
//当前线程拥有对象
//g_hMutex = CreateMutex(0, true, 0);
//ReleaseMutex(g_hMutex);
g_hMutex = CreateMutex(0, false, 0);
HANDLE hThread1 = CreateThread(0, 0, ThreadFun1, 0, 0, 0);
HANDLE hThread2 = CreateThread(0, 0, ThreadFun2, 0, 0, 0);
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(1000);
return 0;
}
DWORD __stdcall ThreadFun1(LPVOID lpParameter)
{
while (1)
{
WaitForSingleObject(g_hMutex, INFINITE);
if (g_resource <= 0)
{
ReleaseMutex(g_hMutex);
break;
}
else
{
cout << "ThreadFun1 used :" << g_resource-- << endl;
ReleaseMutex(g_hMutex);
Sleep(1); //除了等待之外,还会放弃当前的执行权限
}
}
return 0;
}
DWORD __stdcall ThreadFun2(LPVOID lpParameter)
{
//同ThreadFun1
}
三、Event(事件对象)
HANDLE WINAPI CreateEvent(
In_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
In BOOL bManualReset, //手动重置,还是自动重置 (重置为无信号状态)
In BOOL bInitialState, //初始的信号状态
In_opt LPCTSTR lpName
);
部分函数:
ResetEvent //将事件对象设置为无信号状态
SetEvent //将事件对象设置为有信号状态
WaitForSingleObject(); //等待一个对象
代码如下(示例):
#include <iostream>
#include <Windows.h>
using namespace std;
HANDLE g_hEvent; //互斥事件
DWORD WINAPI ThreadFun1(LPVOID lpParameter);
DWORD WINAPI ThreadFun2(LPVOID lpParameter);
int g_resource = 100;
int main()
{
// 手动重置,初始无信号
g_hEvent = CreateEvent(0, true, false, 0);
//设为有信号
SetEvent(g_hEvent);
HANDLE hThread1 = CreateThread(0, 0, ThreadFun1, 0, 0, 0);
HANDLE hThread2 = CreateThread(0, 0, ThreadFun2, 0, 0, 0);
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(1000);
return 0;
}
DWORD __stdcall ThreadFun1(LPVOID lpParameter)
{
while (1)
{
WaitForSingleObject(g_hEvent, INFINITE);
ResetEvent(g_hEvent);
if (g_resource <= 0)
{
SetEvent(g_hEvent);
break;
}
else
{
cout << "ThreadFun1 used :" << g_resource-- << endl;
SetEvent(g_hEvent);
Sleep(1); //除了等待之外,还会放弃当前的执行权限
}
}
return 0;
}
DWORD __stdcall ThreadFun2(LPVOID lpParameter)
{
//同ThreadFun1
}
四、Interlocked(原子锁)
部分函数:
InterlockedIncrement(); //自加
InterlockedDecrement(); //自减
InterlockedOr(); //或
InterlockedAnd //与
等等…
五、信号量
CreateSemaphore();//创建
ReleaseSemaphore();//释放信号
总结
关于线程同步,异步相关的只是还有待进一步发掘@_@