std :: async没有使用std :: launch :: async策略启动新线程

时间:2022-04-04 20:56:18

If I launch std::async with std::launch::async policy shouldn't it start every async task in a new thread? At the moment it looks that new async tasks move to a thread which just completed it's work. I'm using VC11 as my compiler. As you can see from the output when a new worker (e.g. a worker gets a thread with ID 34500 multiple times) is launched with std::async, it starts in a previously finished thread. Is my understanding of std::async wrong or is there an underlying work stealing queue or something of that sort?

如果我用std :: launch :: async策略启动std :: async,它不应该在新线程中启动每个异步任务吗?目前它看起来新的异步任务转移到刚刚完成它的工作的线程。我正在使用VC11作为我的编译器。正如您从输出中看到的那样,当一个新工作者(例如一个工作者多次获得ID为34500的线程)与std :: async一起启动时,它将在之前完成的线程中启动。我对std :: async的理解是错误的还是有一个潜在的工作窃取队列或类似的东西?

Worker (ID=24072) starting.
Worker (ID=34500) starting.
Worker (ID=32292) starting.
Worker (ID=31392) starting.
Worker (ID=17976) starting.
Worker (ID=31580) starting.
Worker (ID=33512) starting.
Worker (ID=33804) starting.
Worker 32292 finished.
Worker (ID=32292) starting.
Worker 17976 finished.
Worker (ID=17976) starting.
Worker 31580 finished.
Worker (ID=31580) starting.
Worker 34500 finished.
Worker (ID=34500) starting.
Worker 34500 finished.
Worker (ID=34500) starting.
Worker 32292 finished.
Worker (ID=32292) starting.
Worker 17976 finished.
Worker (ID=17976) starting.
Worker 34500 finished.
Worker 17976 finished. 
Worker 31580 finished.
Worker 32292 finished.
Worker 33804 finished.
Worker 31392 finished.
Worker 33512 finished.
Worker 24072 finished.

2 个解决方案

#1


11  

If I launch std::async with std::launch::async policy shouldn't it start every async task in a new thread?

如果我用std :: launch :: async策略启动std :: async,它不应该在新线程中启动每个异步任务吗?

The specification requires that the asynchronous operation be executed "as if in a new thread of execution" (C++11 §30.6.8/11). The important words here are: as if.

规范要求“就像在新的执行线程中一样”执行异步操作(C ++11§30.6.8/ 11)。这里重要的话是:好像。

An already-running worker thread can be reused if and only if the behavior is the same as if a new thread was created. This means, for example, that variables with the thread_local storage class must be reset between asynchronous operations executed on a single thread.

当且仅当行为与创建新线程相同时,才能重用已经运行的工作线程。这意味着,例如,必须在单个线程上执行的异步操作之间重置具有thread_local存储类的变量。

It is not necessary that the thread identifier be reset because a thread identifier only uniquely identifies a thread while it is running. If a thread terminates, another thread may be started with the first thread's identifier.

线程标识符不必重置,因为线程标识符仅在线程运行时唯一标识线程。如果线程终止,则可以使用第一个线程的标识符启动另一个线程。

Is there an underlying work stealing queue or something of that sort?

是否有潜在的工作窃取队列或类似的东西?

This is implementation-specific. The Visual C++ 2012 implementation of the C++11 thread support library is built atop the Concurrency Runtime (ConcRT), which includes a work-stealing task scheduler.

这是特定于实现的。 C ++ 11线程支持库的Visual C ++ 2012实现是在并发运行时(ConcRT)之上构建的,其中包括一个工作窃取任务调度程序。

#2


6  

James is right, with one correction: Microsoft implementation of launch::async is incorrect. This was discussed at length by the C++ concurrency working group in Redmond. Visual C++ 2012 is still in beta, so they will probably change the implementation to be Standard compliant.

詹姆斯是对的,有一个更正:微软执行launch :: async是不正确的。 Redmond的C ++并发工作组对此进行了详细讨论。 Visual C ++ 2012仍处于测试阶段,因此他们可能会将实现更改为符合标准。

#1


11  

If I launch std::async with std::launch::async policy shouldn't it start every async task in a new thread?

如果我用std :: launch :: async策略启动std :: async,它不应该在新线程中启动每个异步任务吗?

The specification requires that the asynchronous operation be executed "as if in a new thread of execution" (C++11 §30.6.8/11). The important words here are: as if.

规范要求“就像在新的执行线程中一样”执行异步操作(C ++11§30.6.8/ 11)。这里重要的话是:好像。

An already-running worker thread can be reused if and only if the behavior is the same as if a new thread was created. This means, for example, that variables with the thread_local storage class must be reset between asynchronous operations executed on a single thread.

当且仅当行为与创建新线程相同时,才能重用已经运行的工作线程。这意味着,例如,必须在单个线程上执行的异步操作之间重置具有thread_local存储类的变量。

It is not necessary that the thread identifier be reset because a thread identifier only uniquely identifies a thread while it is running. If a thread terminates, another thread may be started with the first thread's identifier.

线程标识符不必重置,因为线程标识符仅在线程运行时唯一标识线程。如果线程终止,则可以使用第一个线程的标识符启动另一个线程。

Is there an underlying work stealing queue or something of that sort?

是否有潜在的工作窃取队列或类似的东西?

This is implementation-specific. The Visual C++ 2012 implementation of the C++11 thread support library is built atop the Concurrency Runtime (ConcRT), which includes a work-stealing task scheduler.

这是特定于实现的。 C ++ 11线程支持库的Visual C ++ 2012实现是在并发运行时(ConcRT)之上构建的,其中包括一个工作窃取任务调度程序。

#2


6  

James is right, with one correction: Microsoft implementation of launch::async is incorrect. This was discussed at length by the C++ concurrency working group in Redmond. Visual C++ 2012 is still in beta, so they will probably change the implementation to be Standard compliant.

詹姆斯是对的,有一个更正:微软执行launch :: async是不正确的。 Redmond的C ++并发工作组对此进行了详细讨论。 Visual C ++ 2012仍处于测试阶段,因此他们可能会将实现更改为符合标准。