VC下四中线程同步的比较

MFC专门封装了四个类用于实现线程同步。他们都继承自CSyncObject。
  类名 使用方法 适用
临界区 CCriticalSection 只需在线程函数中用CCriticalSection类成员函数Lock()和UnLock()标定出被保护代码片段即可。Lock()后代码用到的资源自动被视为临界区内的资源被保护。UnLock后别的线程才能访问这些资源。 如果有多个线程试图同时访问临界区,那么 在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操 作共享资源的目的。
互斥量 CMutex 使用类成员函数Lock()和UnLock()标定出被保护代码片段即可 互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享
信号量 CSemaphore

信号量对象的成员函数Lock()将计数器的值 -1,当计数器为0时,就不再允许其他线程访问该资源;而当一个线程使用信号量对象的成员函数Unlock()释放资源时,可以将计数器的值 +1。
信号量对象允许多个线程访问同一个资源,但同时访问该资源的线程总数不能超过信号量对象的最大计数值

信号允许多个线程同时使用共享资源
事件 CEvent SetEvent()和ResetEvent().WaitForSingleObject(). f分为自动事件和人工事件。自动事件不需要调用ResetEvent()即在WaitForSingleObject返回时自动将事件设为无信号状态。
总结: 
1. 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量 。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。 
2. 互斥量(Mutex),信号量(Semaphore),事件(Event)都可以被 跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和线程退出。 

3.  如果一个应用同时可以有多个线程存取相应资源,则用CSemaphore;
4.  互斥量和事件属于内核对象,利用内核对象进行线程同步,速度较慢,但利用互斥和事件这样的内核对象,可以在多个进程中的各个线程间进行同步。临界区是工作在用户方式下,同步速度较快,但在使用关键代码段时,很容易进入死锁状态,因为在等待进入关键代码段时无法设定超时值。

---

临界区 CCriticalSection,在用户模式工作,适用于保护线程间共享资源,一个线程可以多次Lock不会出错。不支持在多进程之间工作。

互斥量 CMutex,在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区耗资源。

 事件  CEvent,在内核模式工作,适用于一个线程等待另一个线程完成某任务。

信号量 CSemaphore,在内核模式工作,适用于允许特定个数的线程执行某任务。


参考:
https://blog.csdn.net/ajioy/article/details/7620780
https://blog.csdn.net/tgftd/article/details/76794700
https://www.cnblogs.com/SZxiaochun/p/6845775.html

猜你喜欢

转载自blog.csdn.net/goalcn/article/details/79892428