同步数据结构

并发运行时提供了几个数据结构,利用这些结构可以同步对多个线程中的共享数据的访问。 当您不经常修改共享数据时,这些数据结构很有用。 同步对象(如临界区)会导致其他线程在共享资源可用之前一直等待。 因此,如果使用此类对象来同步对常用数据的访问,则会让应用程序失去可伸缩性。 并行模式库 (PPL)提供了 concurrency::combinable 类,它使您能够共享资源在多个线程或任务,而不需要同步。 有关 combinable 类的更多信息,请参见并行容器和对象

各节内容

本主题详细介绍下列异步消息块类型:

  • critical_section

  • reader_writer_lock

  • scoped_lock and scoped_lock_read

  • 事件

critical_section

Concurrency::critical_section 类代表合作相互排斥对象生成的而不是它们抢占其他任务。 当多个线程需要对共享数据进行独占读写访问时,临界区很有用。

critical_section 类是非重入的。 Concurrency::critical_section::lock 方法将引发的异常类型的 concurrency::improper_lock 如果已经拥有锁的线程调用。

Dd492638.collapse_all(zh-cn,VS.110).gif方法和功能

下表显示 critical_section 类定义的重要方法。

方法

说明

lock

获取临界区。 调用上下文在获取锁之前将阻塞。

try_lock

尝试获取临界区,但不阻塞。

unlock

释放临界区。

Top

reader_writer_lock

Concurrency::reader_writer_lock 类提供对共享数据的线程安全读/写操作。 当多个线程需要对共享资源的并发读访问,但很少需要对该共享资源的写访问时,请使用读取器/编写器锁。 此类任何时候都只允许一个线程对一个对象进行写访问。

reader_writer_lock 类的性能好于 critical_section 类,这是因为 critical_section 对象获取了对共享资源的独占访问权,这将阻止并发读访问。

critical_section 类似,reader_writer_lock 类表示一个协作性互斥对象,该对象将会让位于其他任务,而不是优先于它们。

当某个必须写入一个共享资源的线程获取读取器/编写器锁时,也必须访问该资源的其他线程将被阻塞,直到编写器释放锁。 reader_writer_lock 类是“写优先”锁的一个示例,这种锁会先为等待的编写器解锁,然后再为等待的读取器解锁。

critical_section 类相似,reader_writer_lock 类是非重入的。 Concurrency::reader_writer_lock::lockconcurrency::reader_writer_lock::lock_read 方法引发的异常类型的improper_lock如果已经拥有锁的线程调用。

备注

由于 reader_writer_lock 类是非重入的,因此您无法将只读锁升级为读取器/编写器锁,也无法将读取器/编写器锁降级为只读锁定。执行其中任何一项操作都将产生未指定的行为。

Dd492638.collapse_all(zh-cn,VS.110).gif方法和功能

下表显示 reader_writer_lock 类定义的重要方法。

方法

说明

lock

获取对锁的读/写访问权。

try_lock

尝试获取对锁的读/写访问权,但不阻塞。

lock_read

获取对锁的只读访问权。

try_lock_read

尝试获取对锁的只读访问权,但不阻塞。

unlock

释放锁。

Top

scoped_lock and scoped_lock_read

critical_sectionreader_writer_lock 类提供了嵌套的帮助器类,这些类可简化使用互斥对象的方法。 这些帮助器类称作“范围锁”。

critical_section类包含 concurrency::critical_section::scoped_lock 类。 构造函数获取对提供的 critical_section 对象的访问权;析构函数释放对该对象的访问权。 reader_writer_lock类包含 concurrency::reader_writer_lock::scoped_lock 类,它类似于critical_section::scoped_lock之处在于它管理到所提供的写访问权限、 reader_writer_lock对象。 reader_writer_lock类也包含 concurrency::reader_writer_lock::scoped_lock_read 类。 此类管理对提供的 reader_writer_lock 对象的读访问权。

在手动使用 critical_sectionreader_writer_lock 对象时,范围锁会提供一些好处。 通常,可以在堆栈上分配一个范围锁。 当销毁范围锁时,它会自动释放对其互斥对象的访问权;因此,请不要手动为基础对象解锁。 当函数包含多个 return 语句时,这会很有用。 范围锁还可帮助您编写不会发生异常的代码。 当 throw 语句导致展开堆栈时,将会调用任何活动范围锁的析构函数,因而始终可以正确释放互斥对象。

备注

当使用 critical_section::scoped_lockreader_writer_lock::scoped_lockreader_writer_lock::scoped_lock_read 类时,请不要手动释放对基础互斥对象的访问权。这会导致运行时处于无效状态。

事件

Concurrency::event 类表示可以终止或非终止状态的同步对象。 与用于保护对共享数据的访问的同步对象(如临界区)不同,事件用于同步执行流。

当一个任务已完成另一个任务的工作时,event 类很有用。 例如,一个任务可能告知另一个任务它已从网络连接或文件读取数据。

Dd492638.collapse_all(zh-cn,VS.110).gif方法和功能

下表显示 event 类定义的几个重要方法。

方法

说明

wait

等待事件变为终止状态。

set

将事件设置为终止状态。

reset

将事件设置为非终止状态。

wait_for_multiple

等待多个事件变为终止状态。

Dd492638.collapse_all(zh-cn,VS.110).gif示例

有关说明如何使用 event 类的示例,请参见将同步数据结构与 Windows API 进行比较

Top

相关章节