还是接着讲多线程,照例,可以先看上一篇文章。
我们再次回顾一下上次编写的使用async的多线程程序:
int main()
{async([]{ cout << "Maybe a new thread?" << endl; });cout << "Yeah, u r right!" << endl;return 0;
}
从输出的打印可知,编译器提醒我们不要忽略函数的返回值(即使,这个函数的返回值是 void
)
AsyncTest.cpp: In function 'int main()':
AsyncTest.cpp:9:54: warning: ignoring return value of 'std::future<typename std::__invoke_result<typename std::decay<_Tp>::type, typename std::decay<_Args>::type ...>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = main()::<lambda()>; _Args = {}; typename __invoke_result<typename decay<_Tp>::type, typename decay<_Args>::type ...>::type = void; typename decay<_Tp>::type = main()::<lambda()>]', declared with attribute 'nodiscard' [-Wunused-result]9 | { cout << "Maybe a new thread?" << endl; });| ^
In file included from AsyncTest.cpp:2:
C:/tools/mingw-w64-gcc-13.2-stable-r40/include/c++/13.2.0/future:1828:5: note: declared here1828 | async(_Fn&& __fn, _Args&&... __args)| ^~~~~
Maybe a new thread?
Yeah, u r right!
async
相比thread
的一个优势就是,可以获取线程内函数的返回值,而这个返回值,使用std::future
获取。
std::future
前面提到过,async
是否新开一个线程执行函数,取决于传入的枚举值。当传入deferred
的时候,async
会延迟到get
再执行线程内的函数,实际上就是单线程。而这里的get
就是获取函数返回值的方式。我们改造下上面的代码:
future<int> returnVal = async([] -> int{ cout << "Maybe a new thread?" << endl; return 0; });cout << "Yeah, u r right! val = " << returnVal.get() << endl;
编译器通过future
构造时传入的参数类型认定函数的返回值,并调用get
获取。
future可以调用wait()阻塞主线程等待子线程结束(类似于thread的join()),事实上,当函数返回值为void的时候,调用get
也能起到同样的效果;也可以调用wait_for
,这可以让主线程阻塞一段时间。其参数为C++新引入的chrono::duration
,讲清这个概念估计还得单独开一篇文章(我感觉还不如sleep
好用,可能我工作接触的都是小项目吧)
这里先写几个常见的duration
:
typedef duration<long long, nano> nanoseconds; // 纳秒
typedef duration<long long, micro> microseconds; // 微秒
typedef duration<long long, milli> milliseconds; // 毫秒
typedef duration<long long> seconds; // 秒
typedef duration<int, ratio<60> > minutes; // 分钟
typedef duration<int, ratio<3600> > hours; // 小时
返回值如下:
返回值 | 含义 |
---|---|
future_status::ready | 阻塞时间内,线程结束 |
future_status::timeout | 阻塞时间内,线程未结束 |
future_status::deferred | 线程以非异步方式(deferred)启动,不会阻塞,返回此值 |
示例代码如下:
future<int> returnVal = async([] -> int{ cout << "Maybe a new thread?" << endl; return 0; });returnVal.wait_for(chrono::seconds(10));cout << "Yeah, u r right! val = " << returnVal.get() << endl;return 0;