同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
互斥量的WaitForSingleObject-->ReleaseMute,临界区的EnterCriticalSection-->LeaveCriticalSection,都是必须在同一个线程内执行;
例如:主线程WaitForSingleObjcet或EnterCriticalSection,而在线程函数中ReleaseMutex或 LeaveCriticalSection会执行失败,互斥量和临界区都有线程所有权的概念,互斥量和临界区都是绑定到执行线程;
互斥量,事件,信号量都可以跨进程使用,具体的对象可以通过名字来访问;
举例:跨进程的事件/互斥量通知:
进程A: 事件:HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, _T("Global\\ATestEvent")); // 自动,初始为无信号
互斥量:HANDLE hMutex = CreateEvent(NULL, FALSE, _T("Global\\ATestMutex"));//参数二,FALSE,创建时不属于任何线程,TRUE:创建时属于主进程(Mutex将为当前主线程,即主进程的上锁状态,需要调用ReleaseMutex()才可以跨进程中访问)
if(WAIT_OBJECT_0 == WaitForSingleObject(hMutex, INFINITE))//进锁
ReleaseMutex(hMutex);//释放资源
Global\\**** 可以保证:在创建命名时间对象时指定名字是全局的。这样做的好处如下:
这样创建的内核对象无论出于服务,还是内核中,应用层都可以打开并使用这个内核对象。
进程B: 事件:HANDLE hEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE,_T("Global\\ATestEvent"));
//EVENT_ALL_ACCESS 指定事件对象所有可能的权限
SetEvent(hEvent);//进程A收到相关消息
互斥量: HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, _T("Global\\ATestMutex"));
if(WAIT_OBJECT_0 == WaitForSingleObject(hMutex, INFINITE))//进锁
ReleaseMutex(hMutex);//释放资源
PV操作:
CreateSemaphore; S=1;
WaitForSingleObject; P操作,S-1,大于等于0干活,当S<0,没有资源,继续等待;
ReleaseSemaphore;V操作, S+1,释放资源,唤醒等待
回调函数必须是静态成员函数或全局函数