佛说,彼岸花,开一千年,落一千年,花叶永不相见。情不为因果,缘注定生死。
1 进程的组成:虚拟的地址空间,代码,系统资源。
线程分类:用户界面线程,主线程。举例:CWinApp 就是一个用户界面线程。
线程间通信的方式有两种:1 全局变量 2 自定义消息响应
线程间同步的方式有四种:MFC提供的同步对象
1 临界区 CCriticalSection
2 事件 CEvent
3 互斥量 CMutex
4 信号量 CSemaphore
1 使用场合:当多个线程 访问一个独占性的共享资源
使用方法:(1)定义CCriticalSection 的一个全局对象。 CCriticalSection ;
(2)在需要保护的代码或资源前调用。
critical_section.Lock();
线程调用这个函数Lock()获得临界区对象。如果其他线程没有占有这个临界区对象,调用Lock()的线程获得临界区对象;否则
调用Lock()的线程就被挂起,放入一个由系统维护的队列,直到占有临界区的线程结束为止。
(3)访问临界区完闭,
critical_section.Unlock();
再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其它线程(B)正在执行critical_section.Lock();语句 后且critical_section. Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句 ,线程A才会继续执行。
2 使用场合:CEvent 支持事件。当事件是一个线程在某种情况下用来唤醒另外一个线程的同步对象。
状态:有信号和无信号
分类:自动事件和人工事件。自动和人工的区别是:CEvent 的无信号状态是由系统自动重置的还是有开发者调用函数实现的。
1、CEvent(BOOL bInitiallyOwn=FALSE,
BOOL bManualReset=FALSE,
LPCTSTR lpszName=NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
bInitiallyOwn:指定事件对象初始化状态,TRUE为有信号,FALSE为无信号;
bManualReset:指定要创建的事件是属于人工事件还是自动事件。TRUE为人工事件,FALSE为自动事件;
后两个参数一般设为NULL,在此不作过多说明。
2、BOOL CEvent::SetEvent();
将 CEvent 类对象的状态设置为有信号状态。如果事件是人工事件,则 CEvent 类对象保持为有信号状态,直到调用成员函数ResetEvent()将 其重新设为无信号状态时为止。如果CEvent 类对象为自动事件,则在SetEvent()将事件设置为有信号状态后,CEvent 类对象由系统自动重置为无信号状态。
如果该函数执行成功,则返回非零值,否则返回零。 3、BOOL CEvent::ResetEvent();
该函数将事件的状态设置为无信号状态,并保持该状态直至SetEvent()被调用时为止。由于自动事件是由系统自动重置,故自动事件不需
要调用该函数。如果该函数执行成功,返回非零值,否则返回零。
使用方法:线程(A),线程(B) 如果想先执行线程(A)在执行线程(B),那么在线程(A)中代码的最后调用 CEvent对象的SetEvent(),将事件对象置为有信号状态,在线程(B)代码的开始调用WaitForSingleObject() 那么WaitForSingleObject()函数就可以一直监视CEvent对象一旦此对象为有信号状态那么线程(B)就可以执行了,从而实现了现场同步。
3 互斥对象和临界区很像。CMutex
区别:CMutex既可以在进程间使用,也可以在同一进程的各个线程间使用。
4 CSemaphore
使用场合:允许多个线程同时访问一个共享资源,同时规定了同时访问这个共享资源的线程数目。
其内部有一个计数器当有线程访问这个共享资源时 计数器自动减1 当计数器为0时就不运行其他线程在访问共享资源。
(1)建立一个信号量对象
CSemaphore semaphore(2,2);
定义一个CSingleLock,CMutiLock;
CSingleLock singlelock(semaphore);
要减小这个信号Semaphore的计数值,只须调用CSingleLock对象的成员函数Lock()即可:
SingleLock.Lock();
同样,通过调用UnLock()来释放这个信号量,即:SingleLock.UnLock();
示例代码:http://www.vckbase.com/document/viewdoc/?id=762