2016-05-22 9 views
4

私は、各要素をコンテナから取り出し、アップロード要求をデータベースに送ります。アップロードは同期して行われます。複数のスレッドを待機するstd :: futureまたはstd :: shared_future

コンテナ内の要素は財務契約であり、データ構造コールのティックテーブルが関連付けられている場合とない場合があります。

今、ティックテーブルを持つ契約の場合、私は2回のアップロードをしなければなりません。 1)最初にティックテーブルをdbにアップロードします。 dbはidを返します。 2)IDを契約に添付し、契約をアップロードします。

たとえば、100件の契約を持つコンテナをループしている場合は、30個がティックテーブルを持ち、残りの70個がそうでないとします。

std::futureまたはstd::shared_futureがこのようなタスクに適しているかどうかを確認しようとしていますか?

私は未来を30の契約のそれぞれに関連付けて実装し、launch:asyncポリシーでstd :: asyncを呼び出しました。したがって、ループの最初のパスでは、3つのスレッドが起動され、返される未来は契約に関連付けられたコンテナに「移動」されます。 他の70件の契約は通常の方法でアップロードされます。

2回目のパスでは、get()を保存しておきたいと思います。要求が完了した場合は、IDを取得して契約のアップロードを完了します。将来はコンテナに移動するとスレッドが切り離されると思うので、これはうまくいきません。

私が望む動作を実装するためには、どのようなアプローチをとるべきかアドバイスできますか?

+0

これは同期的に行われていますか?あなたはそれが終わった時の反応を知るでしょう。 – erip

+0

多分、完了したら各ワーカースレッドがその結果をスレッドセーフキューにポストすることができますか? –

+0

ストアドプロシージャがティッカブルと契約を一緒に挿入しないのはなぜですか?それらを分けることにどんな利益がありますか? – ildjarn

答えて

0

未来を移動すると、状態がターゲットに移動します。だから、あなたはあなたが持っていると思う問題はありません。

あなたのティックテーブルソリューションは、未来の未来のように思える - ティックテーブルアップロードの将来の1つ、契約アップロードのための未来。しかし未来の未来はある意味で未来です。

したがって、未来の未来を未来に変える方法があります。

契約タイプがContractであるとします(これは疑似レギュラータイプと見なされます)。チックテーブルIDのバインドは、function<void(Contract&)>の操作です。面白いことに、そのような操作はまた何もできません。

だからstd::future<void(Contract&)> Contract::PrepareForUpload() constです。あなたがアップロードしたい契約ごとに、それのために行く。

ティックテーブルリターンを持つものはstd::asyncで、スレッドを所有するfutureが生成されました。

ティックテーブルを持たないものは、std::asyncにnoop []{return [](auto&&...){};}が含まれています。

次に、std::future<void> Contract::Upload(std::function<void(Contract&>) constを追加します。これで準備コードが実行され、アップロードが行われます(これはなぜですか?後で示します)。

は今すぐアップロードする操作は次のとおりです。

auto prep = contract.PrepareForUpload(); 
auto upload = contract.Upload(prep.get()); 

は今、これは少し面倒です。 2つのことをしていますか? Ick。

どうすればよろしいですか?

std::future<void> Contract::Upload() const { 
    return std::async(
    std::launch::async, 
    [this]{ 
     auto prep = contract.PrepareForUpload(); 
     return contract.Upload(prep.get()); 
    } 
); 
} 

、今Contract::Upload自動的にあなたのための準備アップロードがありません。

しかし、これはティックテーブルのケースで2つのthradsを起動します。 "Upload"の場合に呼び出すことができる同期PrepareForUploadを書きます。

PrepareForUploadに余分な引数が必要な場合は、Uploadに渡すことができます。

この細かいことをする可能性があるとは考えていないことがありますが、将来の連鎖に対する正しい答えは、通常、チェーンを1つの未来に崩壊させることです。

C++ 1zは、.thenと同様の機能性を提案しており、このようなチェーン崩壊を容易かつ効率的にするためです。

+0

ありがとう@ヤク。うわー、未来への未来への畳み込みができることを知ることは素晴らしいことです!私の要求は少しでも簡単でした。契約のアップロードは非同期である必要はありませんでした。基本的には、最初のループを進んでいくうちに、投稿されたすべての非同期ティックテーブルアップロード要求の契約識別子にリンクされた未来のベクトルを保持します。そして、2回目のパスでは、ベクトルのすべての要素に対してget()を行い、返されたticktableidを取得し、各要素にリンクされた契約IDを使用して、契約にticktableidを挿入し、同期アップロードを行います。 – user2930006

関連する問題