线程
从C++11
开始, 标准库支持线程操作, 不再需要写多平台的线程代码了: 使用Windows
下的Create
系列函数以及Linux
下的pthread
系列函数.
thread
thread
是一个线程对象, 它的构造函数可以直接放入要运行的函数以及函数的参数.
demo
首先在子线程中打印参数字符串消息, 然后打印自己的Thread ID
, 最后主线程使用join
等待子线程结束.
#include <thread>
#include <exception>
#include <iostream>
using namespace std;
void func(const string &msg)
{
thread::id thrd_id = this_thread::get_id();
cout << "Other Thread ID: " << thrd_id << endl;
cout << "Message : " << msg << endl;
}
int main()
{
try {
thread::id thrd_id = this_thread::get_id();
cout << "Main Thread ID: " << thrd_id << endl;
thread thrd(func, "hello");
/* do something at main thread */
thrd.join();
} catch (exception &e) {
cout << "Exception: " << e.what() << endl;
}
return 0;
}
注: c++
也支持线程detach
, 但是detach
使用场景很少且很容易出现问题, 最好不要使用detach
.
future & async
future
对象是thread
对象的高层接口, 与async
和get
配合使用, 可理解为处理并发运算的未来结果.
async
对象的构造函数能让一个可被调用的对象成为一个独立的线程并在后台运行.
get
成员函数则用于等待线程结束并获取其结果
关于get
, 需要知道以下五点:
- 如果
async
已经运行完, 则get
能立即获得结果. - 如果
async
运行的线程还未运行完, 则get
与join
的功能相似, 不过get
能获取返回值. - 如果
async
没有运行成功, 则get
函数会同步执行调用可被调用的对象. - 一个
future
对象只能调用一次get
, 之后对象处于无效状态, 只能通过vaild
成员函数检测. - 如果想调用多次
get
, 则需要使用shared_future
对象.
future
demo
计算1~N
的和
#include <future>
#include <exception>
#include <iostream>
using namespace std;
int calc(const int limit)
{
int sum = 0;
for (int num = 1; num <= limit; ++num) {
sum += num;
}
return sum;
}
int main()
{
int limit;
cin >> limit;
try {
future<int> thrd(async(calc, limit));
cout << "Sum of 1 to " << limit << ": " << flush;
int result = thrd.get();
cout << result << endl;
} catch (exception &e) {
cout << "Exception: " << e.what() << endl;
}
return 0;
}
shared_future
demo
promise
demo
others
demo