
三月,你不能跳吗? >>> 
秒杀多线程面试问题系列
参考JustDoIT-大部分内容
什么时候不触发?
何时触发?
WaitForSingleObject的副作用
内核对象
自动重置事件
ResetEvent,PulseEvent或等待成功
SetEvent,PulseEvent
重置通知
手动重置事件
ResetEvent,PulseEvent
SetEvent,PulseEvent
否

自动重置等待计时器
CancelWaitableTimer或等待成功
SetWaitableTimer
重置计时器
手动重置等待计时器
CancelWaitableTimer
SetWaitableTimer
否
信号量
等待成功
当计数大于0(ReleaseSemaphore)时
倒数1
互斥体
等待成功
不被线程(ReleaseMutex)占用时
授予线程所有权
关键部分
等待成功((尝试)EnterCriticalSection)
当不被线程占用时(LeaveCriticalSection)
授予线程所有权
SRWLock
等待成功(获取SRWLock(独家))
不被线程占用时(ReleaseSRWLock(专有)
授予线程所有权
条件变量
等待成功(SleepConditionVariable *)
唤醒(全部)条件变量)
否
同步与互斥之间的区别和联系
互斥: 是指一种资源,它仅允许一个访客同时访问它,这是唯一且排他的. 但是互斥不能限制访问者访问资源的顺序,即访问顺序混乱.

同步: 是指在互斥的基础上通过其他机制有序地对访问者进行资源访问(在大多数情况下). 在大多数情况下,同步已实现互斥,尤其是在所有写入资源必须互斥的情况下. 在极少数情况下,您可以允许多个访问者同时访问资源.
第二个终止多线程处理(第9部分)经典线程同步关键段事件摘要互斥量信号量
当线程并发执行时,由于资源共享和线程合作,线程的使用之间存在两种约束.
(1). 间接的相互制约. 系统中的多个线程必须共享某些系统资源,例如共享的CPU和共享的I / O设备. 所谓的间接相互限制是从这种资源共享中得出的. 打印机是最好的例子. 当线程A使用打印机时,其他线程必须等待.
(2). 直接相互限制. 这种限制主要是由于线程之间的合作. 如果线程A将计算结果提供给线程B进行进一步处理,则线程B将处于阻塞状态,直到线程A发送数据为止.
间接相互限制可以称为互斥,直接相互限制可以称为同步. 对于相互排斥,您可以理解这种方式. 线程A和线程B对资源的互斥访问将导致它们之间的顺序问题-线程A等待线程B完成操作,或者线程B等待线程操作完成,这实际上是线程同步. 因此,同步包括互斥. 互斥实际上是一种特殊的同步.
有两种类型: 用户模式和内核模式. 顾名思义,内核模式是指使用系统内核对象的统一来进行同步. 使用它时,需要在内核模式和用户模式之间切换. 用户模式不需要切换到内核模式,只需完成用户模式下的操作即可.
注意: 因此,就效率而言,关键部分高于互斥对象等.
用户模式下的方法有: 原子操作,临界区,读写锁,条件变量
内核模式下的方法有: 互斥,信号量,事件(手动和自动),等待计时器(手动和自动)

1. 关于线程所有权属性: 也就是说,线程获得同步工具后,可以在释放该工具之前输入多次要访问的资源. 通常,具有所有权属性的工具不用于线程同步,仅出于相互排斥的目的windows 线程同步,您可以参考本文的前几个博客.
2. 内核模式的工具可用于不同进程的线程之间的同步和互斥,而用户模式只能在同一进程的线程之间使用.
3. 当线程异常退出时,只有互斥锁将释放该工具的所有权,其他线程可以继续获取它. 线程异常退出时,其他工具将不会释放,其他线程需要永远等待
4. 该事件分为自动和手动. 如果是自动设置的,则在事件上调用WaitForSingleObject()后,将自动调用ResetEvent()以使事件变为未触发状态.

百度百科
是指由两个或多个进程在执行过程中争用资源或彼此通信而引起的阻塞现象. 没有外力,他们将无法前进. 此时,据说系统处于死锁状态或系统已产生死锁. 这些始终在等待的进程称为死锁进程.
尽管在此过程中可能会发生死锁,但死锁也必须具有某些条件. 死锁必须具有以下四个必要条件.
1)互斥条件: 是指进程分配的资源的互斥,即一个进程在一段时间内仅占用一个资源. 如果此时有其他进程在请求资源,则请求者只能等待直到拥有该资源的进程被释放.
2)请求和保持条件: 这意味着该进程已维护至少一个资源,但发出了新的资源请求,并且该资源已被其他进程占用. 目前,请求过程已被阻止,但是其他Keep资源对此请求不满意.
3)不剥夺条件: 是指进程获得的资源. 它不能在耗尽之前被剥夺,只能在耗尽时自行释放.
4)循环等待条件: 发生死锁时,必须有一个进程-循环资源链-即,进程集中{P0,P1,P2,...windows 线程同步,Pn}中的P0正在等待P1占用的资源; P1正在等待P2占用的资源,...,Pn正在等待P0占用的资源.
一个典型的例子是:
线程A锁定记录1并等待记录2,而线程B锁定记录2并等待记录1,因此这两个线程都有死锁.
可以使用LockCop检测死锁,其源地址为
注意: 此工具使用Windows Vista / 7提供的WCT API,因此您需要在Windows Vista / 7上运行LockCop检测工具.
1)不要程函数体中操作MFC控件,也不要程中调用UpdateData函数来更新用户界面. 而是使用发送消息的方法来操作主线程的消息响应功能中的控件.
注意: 在Winform / WPF中更新线程中的接口将引发异常,解决方案是使用委托.
2)不建议使用SendMessage将消息发送到主线程,因为它是同步且阻塞的,可以考虑改用PostMessage;
3)当线程退出时,尽量不要使用TerminateThread函数,而应让线程尽可能退出自身;
注意: 线程中有诸如malloc / new之类的操作. 强制终止,1将导致内存泄漏,2是因为整个过程在分配和回收内存时必须使用相同的锁. 如果TerminateThread是新的,则非常有用. 可能陷入僵局. CloseHandle(),TerminateThread(),ExitThread()之间的区别
4)当线程退出时,必须在主线程退出之前等待工作线程退出,但不要在主线程中使用WaitForSingleObject或WaitForMultiObjects等待线程结束,因为这可能会导致死锁. 当主线程使用函数Function时,这两个主线程会挂起,尤其是在情况(1),(2)中,工作线程仍在调用主线程中的资源,这会导致死锁;
5)为了防止退出死锁,请尝试使用MsgWaitForMultipleObjects函数,因为当该函数等待时,它可以等待线程句柄发出信号,并且还可以等待消息,这不会导致僵局;
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-146875-1.html
2222222222222222
师傅不健康
╯3╰)