future and promise

When data needs to be passed between two threads, promise and future can be used.

Thread A sets the data through promise.setvalue, and thread B obtains the data from the future after getting the future through promise's get  future. The usage of future is the same as that of the previous blog.

[1] Set data and get data

#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");
}

The results are as follows:

[2] get only, not 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");
}

The child thread will always block on fu.get

[3] set once, get many times

#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");
}

The program will fail to run. When promise set ﹐ value is used, the future will be in ready state, and you can get the value. In the second get, because the future is get once, it cannot be get twice, so the second get will fail. In future design, you can only get once

At the same time, promise can only be set once, not the second time.

The following program will crash

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");
}

If you only set, but not get, there is no problem

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");
}

[4] One thread set, two threads 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");
}

The program will crash.

 

[5] Pay attention. The position of the join should be before the set, otherwise the child thread will wait for no data

#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 after join, the sub thread will wait all the time, and the main thread will wait for the sub thread to finish running before set, so it forms a dead cycle.

	cout << "main" << endl;
	system("pause");
}

 

 

Conclusion: using future and promise to share data among threads is actually a one-time consumption, only one-to-one, and it is a one-time consumption, which can not be used for the second time.

Posted on Fri, 20 Mar 2020 11:23:44 -0700 by rustyofco