MyMSDN

MyMSDN记录开发新知道

关于线程同步的一些总结(用户模式/内核模式)

自旋锁同步

  1. 一般是为了内核态下各个派遣函数之间做同步作用的。
  2. 原理是(单CPU)将IRQL从软件中断提升到硬件中断。PASSIVE_LEVEL->DISPATCH_LEVEL。因为在DISPATCH_LEVEL中是不会出现线程切换的(只有高级别能打断低级别,而低级别不能打断高级别)。
  3. 因为分页内存将导致如果线程切换的时候会引起分页数据交换,数据交换是通过引发页故障来实现的,而页故障是不允许出现在DISPATCH_LEVEL中的,否则将引起系统崩溃(PASSIVE_LEVEL则允许)。驱动程序的StartIO例程、DPC例程、中断服务例程都运行在DISPATCH_LEVEL或者更高的IRQL。因此这些例程不能使用分页内存,否则将导致系统崩溃。
  4. 自旋锁在不同IRP之间同步的时候,则需要放在DeviceExtension中传递。

互锁

  1. 类似于number++; //汇编后将不止一条语句,非原子操作number--; //同上因为语句会变成多句,在线程切换的时候,两个线程下的该例程将会交织在一起执行,导致错误。可以:
    先加锁
    number++;
    解锁
    再加锁
    number--;
    解锁
    来实现两句话的同步(按指定顺序执行,而不受到线程切换的影响)加锁解锁可以使用自旋锁
  2. 在系统中提供了Interlocked***/ExInterlocked***实现

信号灯同步

  1. 线程1关闭信号灯,以至于使用Wait****的时候,当前线程处于暂停状态。
  2. 线程2的作用就是在执行结束后,点亮信号灯(增加计数器)。当线程切换回来的时候,线程1就因为计数器不是0而使信号灯处于激活状态,从而继续执行线程1。

事件的同步

(不能递归获取互斥体)
  1. 主线程在辅助线程上设置了事件,如果不使用Wait**等待事件返回,则主线程可能直接执行完毕了,而导致辅助线程还在执行。
  2. 使用Wait****可以使主线程等待事件执行完成。

互斥体同步

(允许递归获取互斥体(得到互斥体的线程还可以再次获得这个互斥体,或者说互斥体对于已经获得互斥体的线程不产生“互斥”关系))
  1. 创建一个互斥体对象,将互斥体对象传递给多个线程。
  2. 在每个线程操作的步骤中,调用Wait*****,如果互斥体处于激活(内部维护一个计数器),则继续执行后续代码,并在调用结束后恢复互斥体Release****,这样当别的线程试图使用互斥体后面的代码的时候,因为互斥体状态未激活,则无法继续执行代码。

快速互斥体同步

  1. 与互斥体同步类似,唯一区别是不允许递归获取互斥体

posted on 2009-12-26 05:53 volnet 阅读(2056) 评论(2)  编辑 收藏 引用 所属分类: 知识库(KnowledgeLibrary)C/C++

评论

# re: 关于线程同步的一些总结(用户模式/内核模式)[未登录] 2011-05-09 10:22 harryshayne

垃圾  回复  更多评论   

# re: 关于线程同步的一些总结(用户模式/内核模式) 2011-05-10 08:35 愤青

@harryshayne
你蛮无聊的  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


特殊功能