64,646
社区成员
发帖
与我相关
我的任务
分享
#include <chrono>
#include <future>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex g_display_mutex;
void PrintThreadId() {
std::this_thread::sleep_for(std::chrono::seconds(2));
{
std::lock_guard<std::mutex> lock(g_display_mutex);
std::cout << std::this_thread::get_id() << std::endl;
}
}
int main(int argc, char* argv[]) {
std::vector<std::future<void>> futures;
for (int i = 0; i < 10; ++i) {
futures.emplace_back(std::async([]{
return PrintThreadId();
}));
}
for (std::future<void>& future : futures) {
future.wait();
}
}
0: 1
1: 1
2: 1
3: 1
4: 1
5: 1
6: 1
7: 1
8: 1
9: 1
mingw4.8.0 (使用std::launch::async)
5: 7
3: 5
7: 9
1: 3
9: 11
2: 4
0: 2
4: 6
6: 8
8: 10
我稍微改了一下代码,把i值传入线程里了。冒号前面为i值,后面为ThreadId。
3077957328
3077957328
3077957328
3077957328
3077957328
3077957328
3077957328
3077957328
3077957328
3077957328
想要多线程的话,必须这样写。
futures.emplace_back(std::async(std::launch::async, []{
return PrintThreadId();
}));
再次运行的话,输出如下。
3078294384
3069901680
3059411824
3034233712
3042626416
3051019120
3017448304
3025841008
3009055600
3000662896
3078301392
注意 async 的第一个参数需要明确指明 launch::async。这是因为
c++11 30.6.8/3 states
The first function behaves the same as a call to the second function with a policy argument of launch::async | launch::deferred and the same arguments for F and Args. ... The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies).
因此 async(...) == async(launch::async | launch::deferred, ...);
并且实现可以自由选择 async 方式,或 deferred 方式。
该段同时定义了两种方式的行为,见下。
if policy & launch::async is non-zero, calls INVOKE(DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.8.2, 30.3.1.2) as if in a new thread of execution represented by a thread object with the calls to DECAY_COPY () being evaluated in the thread that called async.
同时
if policy & launch::deferred is non-zero, ..., The first call to a non-timed waiting function (30.6.4) on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function.
所以,g++ 选择同一线程以及其它实现选择多线程都符合标准,实际上 30.6.8/9 特地说明了这个问题。
要想确保多线程执行,用户必须自己说清楚。
>>> c++ -std=c++0x -o ttttt ttttt.cpp
ttttt.cpp: In function ‘int main(int, char**)’:
ttttt.cpp:28:34: error: expected initializer before ‘:’ token
ttttt.cpp:31:1: error: expected primary-expression before ‘}’ token
ttttt.cpp:31:1: error: expected ‘;’ before ‘}’ token
ttttt.cpp:31:1: error: expected primary-expression before ‘}’ token
ttttt.cpp:31:1: error: expected ‘)’ before ‘}’ token
ttttt.cpp:31:1: error: expected primary-expression before ‘}’ token
ttttt.cpp:31:1: error: expected ‘;’ before ‘}’ token
我的编译器还没升级到支持C++11 。。。
vegertar@mac:/tmp$ uname -a
Darwin mac.vegertar 13.0.0 Darwin Kernel Version 13.0.0: Thu Sep 19 22:22:27 PDT 2013; root:xnu-2422.1.72~6/RELEASE_X86_64 x86_64
vegertar@mac:/tmp$ c++ -v
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
vegertar@mac:/tmp$ c++ -std=c++11 a.cc
vegertar@mac:/tmp$ ./a.out
0x10e4b2000
0x10e42f000
0x10e3ac000
0x10e535000
0x10e5b8000
0x10e63b000
0x10e6be000
0x10e741000
0x10e7c4000
0x10e847000