读书人

线程同步与互斥的小结

发布时间: 2013-01-26 13:47:01 作者: rapoo

线程同步与互斥的总结

最近回顾了下多线程的一些概念,主要的是线程间的同步以及互斥,简单记录下。


基本概念

2个基本概念:

    同步:按预定的先后次序进行运行。比如:A.B.C3个线程,A先运行,然后B,然后C。互斥:某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
相关函数关键区/临界区 CRITICAL_SECTION临界区的使用比较简单,基本步骤是:初始化--进入--离开--销毁初始化:InitializeCriticalSection进入:EnterCriticalSection离开:LeaveCriticalSection销毁:DeleteCriticalSection
效率最高,单进程内互斥最好。
有线程所有权的概念,所以当前可进入临界区的线程可以多次进入该临界区,所以不能做同步。

互斥量 Mutex互斥量的使用基本步骤:创建--等待对象--释放--关闭创建:CreateMutex等待对象:WaitForSingleObject释放:ReleaseMutex关闭:CloseHandle
跨进程,效率一般,可用于保证只有一个实例被执行,主要是互斥用。
互斥量有线程所有权,所以wait到的线程可以多次wait到,然后进入相关区域。
事件 Event事件的基本使用步骤:创建--set--等待--reset--关闭创建:CreateEventset:SetEvent等待:WaitForSingleObjectreset:ResetEvent 或者 在WaitForSingleObject后自动reset关闭:CloseHandle
跨进程,set后就一直可以等待到,reset后就等待不到了。有一个PulseEvent函数,蛮有趣的,作用是set后立即reset,相当于发射一个脉冲。
没触发就会一直卡在那儿,所以可以用作同步。如果设置了自动重置,那么wait之后,重置了,那就肯定无法再次进入。

信号量 Semaphore信号量的和事件比较类似,基本使用步骤:创建--释放资源--等待--释放资源--关闭创建:CreateSemaphore释放资源:ReleaseSemaphore等待:WaitForSingleObject关闭:CloseHandle
跨进程,等待函数等待成功后,资源计数会-1。如果当前资源计数足够,那么还可以等待到。注意:release的时候,释放数量不可超过设定的资源总数。
类似事件,没有资源就会卡在那儿。

比较分析
    所有都可用于互斥Event和Semaphore可用于同步CriticalSection是非内核对象,相对更加高效
    另外3个都是内核对象,可以跨进程,可用于保证只有一个实例运行另外3个有对应的open函数Event可自动Reset,方便Semaphore可以指定资源数Mutex可以很好的处理“遗弃”问题,即进程结束未释放,会自动释放,对多进程同时使用一个名称的互斥量来说,这是一个好消息
以上,大家各有优缺点,使用时需要根据实际情况选择。


读书人网 >编程

热点推荐