一.事件
可以使用CEvent对象发出通知信号,通知系统是否可以运行等待线程
假设有三个线程Thread1,Thread2,Thread3,一个全局的CEvent 对象oEvent
- UINT
Thread1(LPVOID pParam) - {
-
...... -
oEvent.Lock(); -
...... - }
-
- UINT
Thread2(LPVOID pParam) - {
-
...... -
oEvent.Lock(); -
...... - }
-
- UINT
Thread3(LPVOID pParam) - {
-
...... -
oEvent.SetEvent(); -
...... - }
假设调用过程为:
- AfxBeginThread(Thread1,"Thread1
start"); - AfxBeginThread(Thread2,"Thread2
start");
这样就启动了两个线程,不过都执行到oEvent.Lock()的时候就停止了运行(可以理解为线程入栈).因为此时的oEvent.bInitiallyOwn=FALSE,即禁止发信
这里再启动Thread3,执行到oEvent.SetEvent()的时候,oEvent.binitiallyOwn=TRUE;此时系统发出一个信号通知阻塞的线程,通知的顺序按先进后出的顺序(线程出栈),如上的例子就是先是Thread2被唤醒,Thread2被唤醒之后,马上就将OEvent.bInitiallyOwn的值设置为FALSE,这是CEvent的构造函数第二个参数的意义,自动停止发信.
假如CEvent oEvent(FALSE,TRUE),即创建了一个手动事件对象,与上边自动不同的是,在调用SetEvent()的时候会将所以线程栈当中的阻塞线程一次过唤醒而不停止.
二.临界段
临界是一个公共的资源,当有一个线程希望获取(主要是修改)临界资源的时候,应该先向系统申请,先建立一个对象:
在需要访问临界的线程前加上资源锁:
如果资源没有被其他线程用(锁),就获取资源,否则就阻塞.当这个线程用完资源后,要用
来解除资源锁定,否则其他以后都不能再访问到临界资源三.互斥体
基本与临界一样,只不过临界限定的范围在本进程内,而互斥在不同进程之间都可以互斥
-
CMutex mutexObj(FALSE,"mutex1");//(初始是否锁定,互斥名) -
mutexObj.Lock(); -
mutexObj.UnLock();
三.信号量
信号量就是限制进程同一时间对共享资源同时访问的线程数上限,其他跟临界一样.
-
CSemaphore semaphorObj(2,3);//(计数器初始值,计数器最大值) -
semaphorObj.Lock();//计数器减一,如果为0,则线程阻塞 -
semaphorObj.Unlock();//计数器加一