[C++ Multithreading Series] [10] future and promise

When data needs to be passed between two threads, promises and futures can be used to achieve this.

Thread A sets data through promise.setvalue, and thread B obtains data from future after obtaining future through get_future of promise. The usage of future writing is consistent with the usage of the previous blog post.

[1] Setting data and obtaining 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 result is as follows:

[two] only get, 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 using promise set_value, the future is in the ready state and can get the value. When getting the value for the second time, because the future has been get once and cannot be get the second time, the second get will fail. In future design, you can only get once

At the same time, promises can only be set once, not a 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 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 join should be before set, otherwise the child thread will keep waiting because there is 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在join之后,子线程会一直等待,而主线程也一直在等待子线程运行结束后才会set,所以形成死循环。

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

 

 

Summary: Using futures and promises to share data between threads is actually a one-time consumption, only supports one-to-one, and is a one-time consumption, which cannot be used a second time.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325269210&siteId=291194637