关于unique_lock和lock_guard的区别
unique_lock 和 lock_guard的区别:unique_lock只允许单独获取互斥器的所有权,其区别类似于unique_ptr和shared_ptr的区别。
关于future
future myFuture = async(task, 10);
//这里的async自动创建一个线程执行task函数,并将结果保存到myFuture中,这里future的模板参数要和函数task的返回类型一样。
int x = myFuture.get();
//获得task的执行结果并保存到x中。若task没有执行完就调用get(),那么主线程会阻塞直到task完成。
packaged_task< int(int) > myPackaged(task);
//首先创建packaged_task对象myPackaged其内部创建一个函数task和一个共享状态(用于返回task的结果)。
future myFuture = myPackaged.get_future;
//获取future对象用以返回task的任务结果。
Thread myThread(move(myPackaged),”hello world”);
//move 语义:packaged_task禁止copy constructer,因此用move 强制将左值转右值。
#include <iostream>
#include <functional>
#include <thread>
#include <future>
void print_int (std::future<int>& fut) {
int x = fut.get();
//当promise::set_value()设置了promise的共享状态值后,fut将会通过future::get()获得该共享状态值,若promise没有设置该值那么fut.get()将会阻塞线程直到共享状态值被promise设置
std::cout << "value: " << x << '\n';
}
int main ()
{
std::promise<int> prom; //创建一个promise对象
std::future<int> fut = prom.get_future();
//获取promise内部的future,fut将和promise共享promise中的共享状态,该共享状态用于返回计算结果
std::thread th1 (print_int, std::ref(fut)); //创建一个线程,并通过引用方式将fut传到print_int中
prom.set_value (10); //设置共享状态值
th1.join(); //等待子线程
return 0;
}
将主线程即需要task结果的线程称为provider,称执行任务task或上面print_int的线程为executor(这里只是为了后面表述方便,没有科学考证的)。从上面的例子可以看出,简单的同步机制都是通过设置某种共享状态然后通过future获取该共享状态达到同步。
packaged_task是一个对象其内部持有callable object,provider创建一个下线程executor执行任务,最后provider通过相关的future获取任务计算结果。和async差不多。只有任务结果的存取,没有其它交互。
promise是provider持有,executor持有相关的future,然后provider通过promise设定共享状态的值,future获取该共享值后执行某些任务。形式上和前面两个有点相反。