问题标签 [concrt]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
707 浏览

c++ - 为并发运行时实现任务局部变量

我正在通过使其更加异步来改进应用程序(Win64、C++)。我正在使用并发运行时,到目前为止它对我来说效果很好。

该应用程序基本上执行许多“作业”转换数据。为了跟踪每个作业的功能,某些子系统配备了代码来跟踪作业执行的某些操作。以前,这将使用表示当前正在执行的作业的单个全局变量来注册跟踪信息,而无需将上下文信息一直传递到调用链中。每个作业也可以轮流使用 ConcRT 来并行化作业本身。这一切都很好。

不过,现在我正在重构应用程序,以便我们可以并行执行顶级作业。每个作业都作为 ConcRT 任务执行,这适用于除需要跟踪的作业之外的所有作业。

我基本上需要的是一种将一些上下文信息与任务相关联的方法,并将该流程流向由该任务产生的任何其他任务。基本上,我需要“任务本地”变量。

使用 ConcRT,我们不能简单地使用线程局部变量来存储上下文信息,因为该作业可能会使用 ConcRT 生成其他作业,并且这些作业将在任意数量的线程上执行。

我目前的方法包括在启动时创建许多调度程序实例,并在专用于该作业的调度程序中生成每个作业。然后我可以使用该Concurrency::CurrentScheduler::Id()函数检索一个整数 ID,我可以将其用作找出上下文的键。这是可行的,但是单步执行Concurrency::CurrentScheduler::Id()in 程序集让我有些畏缩,因为它执行多个虚拟函数调用和安全检查,这增加了很多开销,这有点问题,因为这种查找需要以极高的速度完成在某些情况下率。

那么 - 有没有更好的方法来实现这一点?我很想拥有一流的 TaskLocal/userdata 机制,它允许我将单个上下文指针与当前的 Scheduler/SchedulerGroup/Task 相关联,我可以用很少的开销进行检索。

每当 ConcRT 线程抓取新任务时调用的钩子将是我的理想选择,因为我可以检索 Scheduler/ScheduleGroup ID 并将其存储在本地线程中以最小化访问开销。唉,我看不到任何注册这样一个钩子的方法,而且似乎不可能为 PPL/代理实现自定义调度程序类(参见这篇文章)。

0 投票
1 回答
185 浏览

c++ - 为什么我可以选择*不*在运行中调用 Concurrency::agent::done?

这是在 Microsoft C++ 并发 API 的上下文中。

有一个名为agent(在Concurrency命名空间下)的类,它基本上是您派生和实现纯虚拟的状态机agent::run

现在,调用 是您的责任agent::start,这会将其置于可运行状态。然后调用agent::wait* 或其任何变体来实际执行该agent::run方法。

但是为什么我们必须agent::done在体内呼唤呢?我的意思是,显而易见的答案是agent::wait* 将等到发出完成信号或超时已经过去,但是......

设计师的意图是什么?为什么代理agent::run返回时不进入完成状态?这就是我想知道的。为什么我可以选择不打电话done?如果超时已过,wait 方法会抛出异常。