在并发例程中保护共享数据

转载 2008年09月30日 13:46:00
 一次一个!在并发例程中保护共享数据

       聪明的驱动程序编写人员知道 Windows 可以在任何时候抢占线程,而很有可能驱动程序正要在其中运行高优先级线程。并且在多处理器系统(包括带有超线程 CPU 的系统)上,驱动程序可以同时在多个处理器上并发运行。在任何一种情况下,驱动程序都必须同步对共享的可写数据的访问。但是您确切地知道哪些内核模式驱动程序例程可以被并发调用吗?从而确切地知道需要保护哪些数据吗?

可以同时运行的两个例程称为是并发 的。对于驱动程序而言,并发通常意味着操作系统可以在一个例程返回之前调用另一个例程。

当两个例程可以并发运行时,必须确保任何共享的可写数据在同一时间只能被一个例程访问(除非所有这些访问都是只读的)。如果您了解可以并发调用哪些例程,那么必要时可以在驱动程序中使用锁,在某些情况下,可以安排驱动程序的数据结构以避免不必要的锁。

哪些例程可以被并发调用取决于调用的对象。例如,两个被同一个驱动程序对象并发调用的驱动程序例程称为针对驱动程序对象并发。驱动程序例程可以针对驱动程序对象、设备对象或文件对象并发。

驱动程序对象并发。 大部分驱动程序例程针对驱动程序对象并发,因为大部分驱动程序任务都针对特定的文件对象或设备对象进行,而不是针对驱动程序对象本身进行。

设备对象并发。 改变物理设备状态的驱动程序例程(例如即插即用和电源管理调度例程)通常不会针对设备对象并发。

文件对象并发。处理传统 I/O 请求(例如创建、关闭、读取、写入等)的驱动程序例程通常操作文件对象,所以它们的并发性与文件对象的状态相关。例如,驱动程序的 DispatchCleanup 例程直到指向文件对象的句柄被关闭时才被调用。因此,在 DispatchCloseDispatchCreate 例程针对相同的文件对象运行时,不能针对给出的文件对象调用这个例程。

您可以通过检查“内核模式驱动程序的多处理器注意事项”一文中提供的并发表来确定可以并发调用哪些例程。这些表列出针对驱动程序、设备和文件对象并发的例程。

下面展示了来自文件对象并发表的一个摘录:

这个摘录显示 Cancel 例程针对自身以及文件对象调度例程的文件对象并发性。这个表提供下列关于何时可以针对特定的文件对象调用驱动程序的 Cancel 例程的信息:

Cancel 例程运行时,可以针对同一个文件对象再次调用它。这意味着驱动程序必须能够支持同一时间为特定的文件对象同时取消多个 I/O 请求。

当驱动程序的 DispatchCleanup 例程正在运行时(也就是说,当驱动程序在处理特定文件对象的 IRP_MJ_CLEANUP 请求时),可以为文件对象调用驱动程序的 Cancel 例程。

当驱动程序的 DispatchCloseDispatchCreate 例程正在运行时(也就是说,当驱动程序在处理特定文件对象的 IRP_MJ_CLOSE 或 IRP_MJ_CREATE 请求时),不能为文件对象调用驱动程序的 Cancel 例程。(但是,已经计划在 Windows Vista 和 Windows Server 2008 上取消 IRP_MJ_CREATE 请求。)

当驱动程序的任何其他文件 I/O 调度例程正在运行时,可以为同一个文件对象调用 Cancel 例程。

您应该做什么?

识别共享并可能被并发访问的可写数据和内存位置。使用锁来确保所有潜在的并发访问依次发生。

尽可能隔离驱动程序特定的、设备特定的和文件对象特定的数据。

假设您的驱动程序将在多处理器系统上运行,并进行相应的测试。

C++并发实战10:保护共享数据的可选机制

使用mutex的时候要尽量缩小临界区,若可能的话,对mutex加锁仅仅是为了获取共享数据,而对数据的计算放在临界区之外。a lock should be held for only the minim...
  • liuxuejiang158
  • liuxuejiang158
  • 2013年12月12日 11:39
  • 2550

Go并发:访问共享数据

竟险 竟险(竞争条件、Race Condition)是指多个协程(goroutine)同时访问共享数据,其结果取决于指令执行顺序的情况。 考虑如下售票程序。该程序模拟两个售票窗口,一个执行购票,一...
  • u011304970
  • u011304970
  • 2017年05月24日 10:56
  • 546

linux内核中访问共享资源

访问共享资源的代码区域称为临界区,临时以某种互斥机制加以保护。中断屏蔽、原子操作 自旋锁和信号量是Linux设备驱动中可采用的互斥途径。 在单CPU范围内避免竞态的一种简单方法是在进入临界...
  • morixinguan
  • morixinguan
  • 2016年03月08日 22:04
  • 731

保护共享数据

在多线程环境中,读取操作(不管几个线程同时进行)共享数据不会影响到数据的,但是有一个线程或多个线程意图修改数据是,就需要一些机制来保证所有线程都正常工作。   C++中的互斥量 C++标准库中提供了s...
  • Hello_World_LVLcoder
  • Hello_World_LVLcoder
  • 2017年06月22日 20:46
  • 142

C++11 并发教程——Part2:保护共享数据

在前面一篇文章,我们知道怎么使用线程并行地执行程序。在每个线程中执行的代码都是独立的。通常情况下,多个线程之间会用到共享数据。此时,我们就会面临一个问题:同步。 通过下面一段简单的代码来分析...
  • wangyangkobe
  • wangyangkobe
  • 2013年10月28日 22:47
  • 1432

C++11 并发教程第二部分:保护共享数据

程程序,这些在线程中执行的代码都是独立的,但在实际应用中,我们经常会需要线程去访问一些共享的数据,因此也就面临了共享数据的同步问题。 我们先通过一个简单的代码来了解该问题。 同步问题 ...
  • wangweitingaabbcc
  • wangweitingaabbcc
  • 2012年12月22日 11:34
  • 666

Java高并发编程:线程范围内共享数据

笔记摘要所谓线程范围内共享数据,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据,API中为我们提供了一个操作线程范围内共享数据的类Thread...
  • axi295309066
  • axi295309066
  • 2016年10月24日 20:32
  • 1436

synchronized关键字的作用(zz)

   Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized关键字就可以轻松地解决多线程共享数据同步问题。到底如何?――还得对synchronized关键字的作用进行...
  • rainsky_2008
  • rainsky_2008
  • 2005年12月20日 12:10
  • 1207

Java并发编程(五)保护块

5. 保护块线程通常需要协调任务。最常用的协调方法是保护块(guarded block)。这样一个块以一个条件开始,如果该条件为真,则该块的代码得以执行。这样做需要遵循一些步骤。假设,guardedJ...
  • u014088294
  • u014088294
  • 2016年08月15日 21:28
  • 259

共享数据的保护

  • fuzhaoyang
  • fuzhaoyang
  • 2010年03月11日 23:37
  • 275
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在并发例程中保护共享数据
举报原因:
原因补充:

(最多只允许输入30个字)