多线程(进程)的同步对象
来源:互联网 发布:全网通是什么网络制式 编辑:程序博客网 时间:2024/05/16 11:58
-------------------临界区-------------------
critical section不是核心对象,没有handle。
因此它有一个缺陷,就是无法确定进入临界区的线程是否已经结束或死掉。如果进入临界区的线程死掉了但没有调用leave操作,那么系统无法把这个临界区清除。
另一个缺陷是,如果做一件事需要同时进入两个临界区时,就可能出现死锁。而这时却不能使用WaitForMultipleObjects()函数来一次获得两个锁。
也因此有一个优势,进入临界区操作的时间比核心同步对象快很多。
特点:
只能在同一个进程中使用。
不能一次等待多个临界区。
对同一个临界区,在一对EnterCriticalSection()和LeaveCriticalSection()之间,可以嵌套多层该临界区的Enter和Leave。
即一个线程一旦进入一个临界区,它就可以多次进入,但必须要保证有相应次数的离开操作。
critical section的使用:
InitializeCriticalSection()
EnterCriticalSection()
LeaveCriticalSection()
DeleteCriticalSection()
-------------------互斥量-------------------
互斥量是核心对象,有handle。
锁住一个互斥量需要的时间,相当于100倍锁住一个临界区的时间。
特点:
1、可以跨进程使用。(命名互斥量)
2、等待一个互斥量时,可以指定等待结束时间。
3、只能被拥有它的进程(线程)释放。
4、如果线程在拥有一个mutex之后,没有ReleaseMutex()就结束了,则mutex不会被销毁,为被视为“未被拥有”以及“未被激发”,下一个等待操作会返回WAIT_ABANDONED_0。(对waitformultipleobjects()则返回WAIT_ABANDONED_x)。
5、拥有一个mutex后,反复多次调用wait操作,也不会被阻塞。
如果调用CreateMutex()并指定一个已经存在的mutex的名字,则系统会返回这个已经存在的mutex的handle,而不是重新创建一个新的。
如果mutex未被任何线程(或进程)拥有,则mutex处于激发状态(有信号状态)。(准确地说,是未被拥有且被wait时,处于激发状态。)
核心对象的handle有引用计数。在其计数降为0时被操作系统销毁。
拥有核心对象handle的线程结束时(或调用CloseHandle()),该handle的计数会减少1。(线程结束,系统会自动释放该线程拥有的handle ???)
mutex的使用:
CreateMutex()/OpenMutex()
WaitForSingleObject()/WaitForMultipleObjects()/MsgWaitForMultipleObjects()
ReleaseMutex()
CloseHandle()
-------------------------信号量-----------------------
是核心对象,有handle。
是解决生产者/消费者问题的常用方法。比如环状缓冲区。
信号量可以表达资源的数量,所以适合管理一组相同的资源。
mutex是semaphore的特例,是只有一个资源的semaphore。mutex也称为binary semaphore。
特点:
1、可以指定名字。
2、可以跨线程使用。
3、没有拥有者。没有拥有权的概念,可以被多个线程锁定。也可以被一个线程反复多次锁定(是多个锁定)。
4、可以被任何线程(进程)释放。调用ReleaseSemaphore()的线程,可以不必是wait操作的那个线程。即任何线程都可以释放信号量。
在CreateSemaphore()时,如果指定名字的信号量已经存在,函数仍然可以成功(和mutex的创建相同),但GetLastError()返回ERROR_ALREADY_EXISTS。
信号量的使用:
CreateSemaphore()
WaitForSingleObject()/WaitForMultipleObjects()/MsgWaitForMultipleObjects()
ReleaseSemaphore()
CloseHandle()
----------------------------事件-------------------------
是核心对象,有handle。
特点:
可以自己控制事件对象的状态(有无信号状态)。可以和mutex、semaphore不一样,状态的变化可不是因为wait操作导致。(在创建时设置为手动reset)。
可以有名字。可以跨线程。
在CreateEvent()时,如果指定名字的事件已经存在,函数仍然可以成功(和mutex的创建相同),但GetLastError()返回ERROR_ALREADY_EXISTS。
事件的用法:
CreteEvent()
SetEvent()/PulseEvent()
WaitForSingleObject()/WaitForMultipleObjects()/MsgWaitForMultipleObjects()
ResetEvent()
CloseHandle()
PulseEvent(): 把事件设置为激发状态(有信号状态)。
当事件为ManualReset时,会唤醒所有等待这个事件的线程。
当事件为AutoReset时,会唤醒其中一个等待这个事件的线程。
如果没有线程正在等待,那么PulseEvent()操作产生的激发状态不会被储存,造成事件丢失。即激发是瞬时状态。如果问题的解决方案中存在事件丢失造成程序错误这种可能,则可以使用semaphore。
---------------Interlocked函数--------------
它没有等待的功能,只完成对int数据的原子化操作。InterlockedDecrement(): 把参数减1,然后和0比较,如果大于0返回正数,如果等于0返回0,如果小于0返回负数。
InterlockedIncrement(): 同上。
InterlockedExchange(LPLONG lpTarget, LONG lValue);
0 0
- 多线程(进程)的同步对象
- 多进程/多线程的同步
- 多线程多进程同步技术的选择
- Java(8-2)多线程的同步和条件对象
- Windows多线程/进程同步(1)
- 多线程 : 进程同步
- Linux 多线程/进程同步
- c++多线程同步使用的对象
- Linux多线程之同步对象的比较
- c++多线程同步使用的对象
- 多线程同步之Event(事件对象)
- Java多线程-线程同步(对象锁)
- 多线程同步对象汇总
- linux 多线程 多进程同步
- 进程内多线程同步CRITICAL_SECTION
- Window进程内多线程同步
- 多线程,进程,同步互斥
- 多进程、多线程、同步、通信
- 构造代码块 VS 静态代码块
- 基于.Net的单点登录(SSO)解决方案
- HDOJ——5171(矩阵乘方)
- hadoop
- .net中Cache的应用
- 多线程(进程)的同步对象
- linux vi命令详解
- LeetCode Swap Nodes in Pairs
- CodeForces 274A k-Multiple Free Set
- R语言微博数据处理(2)
- Listview详解
- 冒泡快速等算法总结
- Codeforces GYM 100548 I - International Collegiate Routing Contest 2014 ACM Xian Regional Contest
- python正则表达式