上下文

本文档介绍并发运行时中上下文的角色。 附加到计划程序的线程称为“执行上下文”或简称为“上下文”。 Concurrency::wait 函数和 concurrency::Context 类使您能够控制环境的行为。 使用 wait 函数可在指定的时间段内挂起当前上下文。 当您需要对上下文何时阻止、取消阻止和让出资源,以及何时要超额订阅当前上下文进行更多控制时,可使用 Context 类。

提示

并发运行时提供默认的计划程序,因此您不需要在应用程序中再创建一个计划程序。由于任务计划程序可帮助您优化应用程序的性能,因此,如果您初次接触并发运行时,则建议您先使用 并行模式库 (PPL)异步代理库

wait 函数

Concurrency::wait 函数彼此产生执行指定的毫秒数的当前上下文。 运行时使用让出时间来执行其他任务。 指定的时间过去后,运行时重新计划执行上下文。 因此,wait 函数挂起当前上下文的时间可能长于为 milliseconds 参数提供的值。

对 milliseconds 参数传递 0(零)会导致运行时挂起当前上下文,直到为所有其他活动上下文提供了执行工作的机会。 这样,您便可以将一个任务的资源让出给所有其他活动任务。

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

有关使用 wait 函数让出当前上下文的资源,以便允许其他上下文运行的示例,请参见如何:使用计划组影响执行顺序

Context 类

Concurrency::Context 类提供了编程抽象的执行上下文,并提供了两个重要功能: 能够彼此阻止、 解除锁定,并产生当前上下文中,并能够超额订阅当前上下文。

Ff829266.collapse_all(zh-cn,VS.110).gif协作阻止

利用 Context 类,可以阻止或退出当前执行上下文。 在当前上下文由于资源不可用而无法继续时,可使用阻止或让出功能。

Concurrency::Context::Block 方法将阻止当前上下文。 被阻止的上下文让出其处理资源,以便运行时可执行其他任务。 Concurrency::Context::Unblock 方法取消阻止已阻止的上下文。 必须从调用 Context::Block 的上下文之外的其他上下文调用 Context::Unblock 方法。 运行库会引发 concurrency::context_self_unblock 如果尝试取消阻止本身的上下文。

彼此阻止和取消阻止一个上下文,您通常调用 concurrency::Context::CurrentContext 检索指向Context ,并保存结果与当前线程相关联的对象。 然后调用 Context::Block 方法以阻止当前上下文。 接下来,从另一个上下文调用 Context::Unblock 以取消阻止被阻止的上下文。

每一对调用都必须与 Context::BlockContext::Unblock 相匹配。 运行库会引发 concurrency::context_unblock_unbalancedContext::BlockContext::Unblock不匹配的调用其他方法的情况下连续调用方法。 但是,在调用 Context::Unblock 之前不必调用 Context::Block。 例如,如果一个上下文在另一个上下文针对该上下文调用 Context::Block 之前调用 Context::Unblock,则该上下文保持取消阻止。

Concurrency::Context::Yield 方法放弃执行,以便在运行时可以执行其他任务,然后重新安排的执行上下文。 当您调用 Context::Block 方法时,运行时不重新计划上下文。

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

有关使用 Context::BlockContext::UnblockContext::Yield 方法实现协作信号量类的示例,请参见如何:使用上下文类实现协作信号量

Ff829266.collapse_all(zh-cn,VS.110).gif过度订阅

默认计划程序创建的线程数与可用硬件线程的数量相同。 使用过度订阅可为给定的硬件线程创建附加线程。

对于计算量相当大的操作,过度订阅通常不会带来优势,因为它引入了额外的系统开销。 但是,对于延迟时间很长的任务(例如从磁盘或通过网络连接读取数据),过度订阅可以提高某些应用程序的总体效率。

备注

启用超额预定只能从创建并发运行的线程。如果从不是由运行时创建的线程(包括主线程)中调用过度订阅,则过度订阅将不起作用。

若要启用超额预定在当前上下文中的,调用 concurrency::Context::Oversubscribe 方法使用_BeginOversubscription参数设置为true。 当在并发运行时创建的线程上启用过度订阅时,它导致该运行时创建一个附加线程。 当需要过度订阅的所有任务完成后,调用 Context::Oversubscribe,并将 _BeginOversubscription 参数设置为 false。

您可以从当前上下文多次启用过度订阅,但禁用它的次数必须与启用它的次数相同。 也可以嵌套过度订阅;也就是说,由使用过度订阅的另一任务创建的任务也可以过度订阅其上下文。 但是,如果嵌套的任务和其父任务属于同一上下文,则只有对 Context::Oversubscribe 的最外层调用会导致创建附加线程。

备注

运行库会引发 concurrency::invalid_oversubscribe_operation 如果超额预定之前启用将被禁用。

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

有关使用过度订阅来抵销通过网络连接读取数据导致的延迟的示例,请参见如何:使用过度订阅抵消延迟

请参见

任务

如何:使用计划组影响执行顺序

如何:使用上下文类实现协作信号量

如何:使用过度订阅抵消延迟

概念

任务计划程序(并发运行时)