C++ 11 线程 promise、future、async、packaged_task

1.promise和future

Role and future promise is to pass data between different threads. It can also be done using the pointer to transfer data, but the pointers are very dangerous because the mutex can not block access to the pointer; pointer and data transfer method is fixed, if you change the data type, you also need to change about the interface, more trouble ; promise support for generics operations more convenient programming process.

Suppose a thread for a thread 2 data, then use the following combination:

Thread 1 initializes a future target object and a promise, promise to transfer the thread 2, a commitment corresponding to thread 1, thread 2; corresponding to a future accepts a promise for the future value of the thread 2 acquires the transmitting
thread 2 acquires promise , you need to transfer data related to this promise, then thread the future 1 can get the data.
If you want to get data thread 1, thread 2 and data not shown, the thread 1 block until the data reaches the thread 2.

Thread 1 is detected as long as the data arrives, get on it, the state of the thread 2 can end may continue to run.

// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

// 计算一个vector数组的和,并设置一个promise,这是一个承诺,需要设置这个值
void accumulate(std::vector<int>::iterator first,
	std::vector<int>::iterator last,
	std::promise<int> accumulate_promise)
{
	int sum = std::accumulate(first, last, 0);
	std::cout << "set promise\n";
	accumulate_promise.set_value(sum);// Notify future
	std::this_thread::sleep_for(std::chrono::seconds(10));
}

void do_work(std::promise<void> barrier)
{
	std::this_thread::sleep_for(std::chrono::seconds(1));
	barrier.set_value();
	std::this_thread::sleep_for(std::chrono::seconds(10));
}

int main()
{
	// Demonstrate using promise<int> to transmit a result between threads.
	std::vector<int> numbers = { 1,2,3,4,5,6 };
	std::promise<int> accumulate_promise;
	std::future<int> accumulate_future = accumulate_promise.get_future();
	std::thread work_thread(accumulate, numbers.begin(), numbers.end(), std::move(accumulate_promise));

	std::cout << "result=" << accumulate_future.get() << "\n";
	work_thread.join();

	std::promise<void> barrier;
	std::future<void> barrier_future = barrier.get_future();
	std::thread new_work_thread(do_work, std::move(barrier));
	barrier_future.wait();
	new_work_thread.join();
    return 0;
}

 

2.async

(Advanced Packaging future and thread)

runs a function asynchronously (potentially in a new thread) and returns a std::future that will hold the result

Asynchronous run a function (probably in the new thread) and returns to save the results of std :: future

// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

bool is_prime(int x)
{
	for (int i = 2; i < x; i++) {
		if (x%i == 0)
			return false;
	}
	return true;
}

int main()
{
	// call function asynchronously;
	std::future<bool> fut = std::async(is_prime, 4444444443);

	// do something while waiting for function to set future.
	std::cout << "checking,please wait...";
	std::chrono::milliseconds span(100);
	while (fut.wait_for(span) == std::future_status::timeout)
	{
		std::cout << '.' << std::flush;
	}
	bool x = fut.get();
	std::cout << "\n4444444443 " << (x ? "is" : "is not") << " prime.\n";

    return 0;
}

operation result:

After std :: async will first create a thread execution is_prime (4444444443), job creation, std :: async returns a std :: future objects immediately.

 The main thread can use std :: future :: get get results, if the calling process, the task has not been completed, the main thread is blocked until the task is completed.

 The main thread can also use std :: future :: wait_for wait for the results returned, wait_for can set the timeout, if the task is completed within the timeout period, the returns std :: future_status :: ready state; if the task within the time-out yet complete, std :: future_status returns :: timeout status.

3.packaged_task

std :: packaged_task role is to provide a data synchronization mechanism between the different threads, a function which can store operation, and returns the value passed to the corresponding future, but in the future may be another thread to secure access this value.

Sample code:

// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

int countdown(int from, int to)
{
	for (int i = from; i != to; --i)
	{
		std::cout << i << '\n';
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	std::cout << "Lift off!\n";
	return from - to;
}

int main()
{
	std::packaged_task<int(int, int)> tsk(countdown);
	std::future<int> ret = tsk.get_future();
	std::thread th(std::move(tsk), 10, 0);
	// ...
	int value = ret.get();// wait for the task to finish and get result
	std::cout << "The countdown lasted for " << value << " seconds.\n";
	th.join();
    return 0;
}

operation result:

Published 257 original articles · won praise 22 · views 90000 +

Guess you like

Origin blog.csdn.net/qq_24127015/article/details/104819447