C++11中std::shared_futureの使用


C++11のstd::shared_futureはテンプレートクラスです.std::futureと同様、std::shared_futureは非同期操作結果にアクセスするメカニズムを提供する.std::future,std::shared_とは異なりますfutureは、複数のスレッドが同じ共有状態を待つことを可能にする.stdとは異なります::futureは移動操作のみをサポートし、std::shared_futureは、移動操作もコピー操作もサポートし、複数のshared_futureオブジェクトは、同じ共有状態を参照できます.std::shared_futureはまた、共有状態が完了すると、共有状態の値(A shared_future object behaves like a future object,except that it can be copied,and that more than one shared_future can share ownership over their end of a shared state.They also allow the value in the shared state to be retrieved multiple times once ready)を複数回検索することを可能にする.
std::shared_futureオブジェクトは、std::futureオブジェクトを暗黙的に変換するか、std::future::shareを表示して変換を表示するかのどちらの場合も、元のstd::futureオブジェクトは無効になります.
共有状態(shared state)の生存期間は、少なくとも関連する最後のオブジェクトが破棄されるまで継続しなければならない.std::futureとは異なりshared_future::getが取得した値は共有オブジェクトの所有権を解放しません.
std::future紹介参考:https://blog.csdn.net/fengbingchun/article/details/104115489
std::futureの複数の有効なコピーが必要な場合はstd::shared_future;あるいは複数の利用者がstd::futureを使用する場合もstd::shared_future.
Consider std::future, std::shared_future to be like std::unique_ptr, std::shared_ptr.
テンプレートクラスstd::shared_futureメンバー関数には、次のものがあります.
1.コンストラクション関数:(1).パラメータを持たないデフォルトのコンストラクション関数です.このオブジェクトには共有状態がないため、無効ですが、有効な値を与えることができます.(2).コピー構造:const shared_とfuture&xは同じ共有状態を有し、所有権を共有する.(3).モバイル構造をサポートします.
2.構造関数:shared_を破棄するfutureオブジェクト、異常に安全です.オブジェクトが有効である(すなわち、共有ステータスにアクセスできる)場合は、オブジェクトコンタクトに関連付けられます.共有ステータスに関連付けられた一意のオブジェクトである場合、共有オブジェクト自体も破棄されます.
3.get関数:(1).共有ステータスが完了すると、共有ステータスに格納されている値の参照(または例外を放出)が返されます.(2).共有ステータスがまだ準備されていない場合(providerプロバイダが値または例外を設定していない場合)、関数は呼び出したスレッドを準備が整うまでブロックします.(3).共有ステータスが準備完了すると、関数はブロックを解除して戻ります(または投げ出されます)が、future::getとは異なり、共有ステータスは解放されず、他のshared_を許可します.futureオブジェクトも格納された値にアクセスします.(4).std::shared_future::get()は値を返さないが、共有ステータスが完了するまで待機している.
4. operator=:(1).コピー割り当て:オブジェクトとconst shared_future&rhsは同じ共有状態に関連付けられ、所有権を共有する.(2).割り当ての移動:オブジェクト取得shared_future&&rhsの共有状態ではrhsは有効ではありません.
5.valid関数:共有状態の有効性をチェックし、現在のshared_を返します.futureオブジェクトが共有状態に関連付けられているかどうか.
6.wait関数:(1).共有ステータスの準備が完了するまで待機します.(2).共有ステータスがまだ準備されていない(すなわち、プロバイダが値または例外を設定していない)場合、関数は呼び出したスレッドを準備が整うまでブロックします.(3).共有ステータスが完了すると、関数はブロックを解除しvoidが返されます.
7. wait_for関数:(1).共有状態が指定された時間内に準備が完了するのを待つ.(2). 共有ステータスがまだ準備されていない(すなわち、プロバイダが値または例外を設定していない)場合、関数は呼び出したスレッドを準備完了または設定に達した時間までブロックします.(3).この関数の戻り値タイプは、列挙クラスfuture_です.status.この列挙クラスには、3つのlabelがあります.ready:共有ステータスが準備されています.timeout:指定した時間内に準備ができていない;deferred:共有状態には遅延関数(deferred function)が含まれています.(4).共有ステータスに遅延関数が含まれている場合、その関数はブロックされず、すぐにfuture_を返します.status::deferred値.
8. wait_until関数:(1).共有ステータスが指定された時点で準備完了するのを待つ.(2). 共有ステータスがまだ準備されていない(すなわち、プロバイダが値または例外を設定していない)場合、関数は呼び出したスレッドを準備完了または指定された時点に達するまでブロックします.(3).この関数の戻り値タイプは、列挙クラスfuture_です.status.(4).共有ステータスに遅延関数が含まれている場合、その関数はブロックされず、すぐにfuture_を返します.status::deferred値.
詳細な使い方は以下のテストコードを参照してください.以下は他の文章のcopyのテストコードです.詳細は対応するreferenceを参照してください.
#include "future.hpp"
#include 
#include 
#include 
#include 
#include 

namespace future_ {

///////////////////////////////////////////////////////////
// reference: https://en.cppreference.com/w/cpp/thread/shared_future
int test_shared_future_1()
{
	std::promise ready_promise, t1_ready_promise, t2_ready_promise;
	//   std::future    std::shared_future  ,t1_ready_promise t2_ready_promise    ready_future
	std::shared_future ready_future(ready_promise.get_future());

	std::chrono::time_point<:chrono::high_resolution_clock> start;

	auto fun1 = [&, ready_future]() -> std::chrono::duration {
			t1_ready_promise.set_value();
			ready_future.wait(); // waits for the signal from main()
			return std::chrono::high_resolution_clock::now() - start;
		};

	auto fun2 = [&, ready_future]() -> std::chrono::duration {
		t2_ready_promise.set_value();
		ready_future.wait(); // waits for the signal from main()
		return std::chrono::high_resolution_clock::now() - start;
	};

	auto fut1 = t1_ready_promise.get_future();
	auto fut2 = t2_ready_promise.get_future();

	auto result1 = std::async(std::launch::async, fun1);
	auto result2 = std::async(std::launch::async, fun2);

	// wait for the threads to become ready
	fut1.wait();
	fut2.wait();

	// the threads are ready, start the clock
	start = std::chrono::high_resolution_clock::now();

	// signal the threads to go
	ready_promise.set_value();

	std::cout << "Thread 1 received the signal " << result1.get().count() << " ms after start
" << "Thread 2 received the signal " << result2.get().count() << " ms after start
"; return 0; } /////////////////////////////////////////////////////////// // reference: https://en.cppreference.com/w/cpp/thread/shared_future/wait int fib(int n) { if (n < 3) return 1; else return fib(n - 1) + fib(n - 2); } int test_shared_future_2() { // std::shared_future std::future std::shared_future f1 = std::async(std::launch::async, []() { return fib(20); }); std::shared_future f2 = std::async(std::launch::async, []() { return fib(25); }); std::cout << "waiting...
"; f1.wait(); f2.wait(); std::cout << "f1: " << f1.get() << '
'; std::cout << "f2: " << f2.get() << '
'; return 0; } /////////////////////////////////////////////////////////// // reference: https://en.cppreference.com/w/cpp/thread/shared_future/wait_for int test_shared_future_3() { // std::shared_future std::future std::shared_future future = std::async(std::launch::async, [](){ std::this_thread::sleep_for(std::chrono::seconds(3)); return 8; }); std::cout << "waiting...
"; std::future_status status; do { status = future.wait_for(std::chrono::seconds(1)); if (status == std::future_status::deferred) { std::cout << "deferred
"; } else if (status == std::future_status::timeout) { std::cout << "timeout
"; } else if (status == std::future_status::ready) { std::cout << "ready!
"; } } while (status != std::future_status::ready); std::cout << "result is " << future.get() << '
'; return 0; } } // namespace future_

GitHub:https://github.com/fengbingchun/Messy_Test