当两个线程间需要传递数据时,可以使用promise与future来实现。
线程A通过promise.setvalue来设置数据,线程B通过promise的get_future获取future后,从future中获取数据。future写用法与前面博文用法一致。
【一】设置数据与获取数据
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
void f(future<int> &fu)
{
cout << fu.get() << endl;
}
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
thread t1(f, std::ref(fu));
pro.set_value(10);
t1.join();
cout << "main" << endl;
system("pause");
}
结果如下:
【二】只get,不set
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
void f(future<int> &fu)
{
cout << fu.get() << endl;
}
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
thread t1(f, std::ref(fu));
//pro.set_value(10);
t1.join();
cout << "main" << endl;
system("pause");
}
子线程会一直阻塞在fu.get上
【三】set一次,get多次
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
void f(future<int> &fu)
{
cout << fu.get() << endl;
cout << fu.get() << endl;
}
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
thread t1(f, std::ref(fu));
pro.set_value(10);
t1.join();
cout << "main" << endl;
system("pause");
}
程序会运行失败。当使用promise set_value时,future便处于ready状态,可以get到值,第二次get时,由于future被get了一次,不可以被get第二次,所以第二次get会失败。future设计上,就是只能get一次
同时,promise只能被set一次,不能被set第二次。
如下程序会崩溃
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
//thread t1(f, std::ref(fu));
pro.set_value(10);
pro.set_value(10);
//t1.join();
cout << "main" << endl;
system("pause");
}
如果只set,而没有get,是没有问题的
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
//thread t1(f, std::ref(fu));
pro.set_value(10);
//pro.set_value(10);
//t1.join();
cout << "main" << endl;
system("pause");
}
【四】一个线程set,两个线程get
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
void f(future<int> &fu)
{
cout << "f"<<fu.get() << endl;
//cout << fu.get() << endl;
}
void f2(future<int> &fu)
{
cout << "f2"<<fu.get() << endl;
//cout << fu.get() << endl;
}
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
thread t1(f, std::ref(fu));
thread t2(f, std::ref(fu));
pro.set_value(10);
//pro.set_value(10);
t1.join();
t2.join();
cout << "main" << endl;
system("pause");
}
该程序会崩溃。
【五】注意点。join的位置应该在set之前,否则子线程会由于没有数据而一直等待
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
void f(future<int> &fu)
{
cout << "f"<<fu.get() << endl;
}
int main(int argc, int * argv[])
{
promise<int> pro;
future<int> fu = pro.get_future();
thread t1(f, std::ref(fu));
t1.join();
pro.set_value(10); // set在join之后,子线程会一直等待,而主线程也一直在等待子线程运行结束后才会set,所以形成死循环。
cout << "main" << endl;
system("pause");
}
总结:使用future与promise进行线程间数据共享,实际上是一种一次性消费,仅支持一对一,而且是一次性消费,不能再使用第二次。