同步数据结构

并发运行时提供了几种数据结构,用于同步对来自多个线程的共享数据的访问。 当你有不经常修改的共享数据时,这些数据结构很有用。 一个同步对象,例如,一个关键部分,会导致其他线程等待,直到共享资源可用。 因此,如果使用这样的对象来同步对经常使用的数据的访问,会失去应用程序的可扩展性。 并行模式库 (PPL) 提供了 concurrency::combinable 类,使你能够在无需同步的情况下在几个线程或任务之间共享资源。 有关 combinable 类的详细信息,请参阅并行容器和对象

章节

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

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 类时,不要手动释放对基础互相排斥对象的访问权限。 这会将运行时置于无效状态。

event

concurrency::event 类表示一个同步对象,此对象的状态可以是信号通知的,也可以是非信号通知的。 与同步对象(如关键部分)不同,其用途是保护对共享数据的访问,事件会同步执行流。

当一个任务完成另一个任务的工作时,event 类非常有用。 例如,一个任务可能会向另一个任务发出信号,告知它已从网络连接或文件中读取数据。

方法和功能

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

方法 说明
wait 等待事件变为发出信号状态。
set 将事件设置为信号通知状态。
reset 将事件设置为非信号通知状态。
wait_for_multiple 等待多个事件变为信号通知状态。

示例

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

[返回页首]

将同步数据结构与 Windows API 进行比较
将同步数据结构的行为与 Windows API 所提供的结构进行比较。

并发运行时
描述可以简化并发编程并包含相关主题链接的并发运行时。