同步数据结构

并发运行时提供了几个数据结构,利用这些结构可以同步对多个线程中的共享数据的访问。 当您不经常修改共享数据时,这些数据结构很有用。 同步对象(如临界区)会导致其他线程在共享资源可用之前一直等待。 因此,如果使用此类对象来同步对常用数据的访问,则会让应用程序失去可伸缩性。 并行模式库 (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 的异常。

方法和功能

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

方法

说明

lock

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

try_lock

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

unlock

释放临界区。

[转到页首]

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 类是非重入的,因此您无法将只读锁升级为读取器/编写器锁,也无法将读取器/编写器锁降级为只读锁定。 执行其中任何一项操作都将产生未指定的行为。

方法和功能

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

方法

说明

lock

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

try_lock

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

lock_read

获取对锁的只读访问权。

try_lock_read

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

unlock

释放锁。

[转到页首]

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 类很有用。 例如,一个任务可能告知另一个任务它已从网络连接或文件读取数据。

方法和功能

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

方法

说明

wait

等待事件变为终止状态。

set

将事件设置为终止状态。

reset

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

wait_for_multiple

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

示例

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

[转到页首]

相关章节