2

この簡単な例では、どのようにして

   a->push_back(i)

スレッドが開始された順序で発生しますか?したがって、内容は{1,2,3}になります。

#include <vector>
#include <thread>

void do_stuf(int i,std::vector<int> * a)
{
    //do very long stuff
    a->push_back(i);
}


int main()
{
    std::vector<int> tmp;
    std::thread t1(do_stuf,1,&tmp);
    std::thread t2(do_stuf,2,&tmp);
    std::thread t3(do_stuf,3,&tmp);

    t1.join();
    t2.join();
    t3.join();
}
4

5 に答える 5

5

1つの方法は、次のように、スレッドに結果を保存する場所へのポインターまたは参照を渡すことです(そして、スレッドの存続期間中に割り当てられたままであることを確認します)。

void do_stuf(int i, int* a)
{
    //do very long stuff
    *a = i;
}


int main()
{
    std::vector<int> tmp(3);
    std::thread t1(do_stuf,1,&tmp[0]);
    std::thread t2(do_stuf,2,&tmp[1]);
    std::thread t3(do_stuf,3,&tmp[2]);

    t1.join();
    t2.join();
    t3.join();
}

あなたが何を達成しようとしているのかはあなたの例からは明らかではありませんが、std::promiseとstd::futureを見て、それらが何をするのか理解しましたか?彼らはあなたが望むものかもしれません。

(このコンテキストでのvector :: push_backの問題は、スレッドセーフではないことです。2つのpush_backsの実行が重複する場合、同じ要素を上書きしたり、すべての要素の格納場所を移動して配列を再割り当てしたりする可能性があります。)

于 2012-07-31T18:49:32.457 に答える
0

これにはいくつかの方法でアプローチできます。結果の順序だけを気にしない場合は、タスクIDとその結果を使用してオブジェクトをプッシュし、タスクIDでオブジェクトを並べ替えて、すべてが完了したら印刷します。

前のタスクが完了するまで実際にレポートしないようにする場合は、前のタスクを待つ必要があります。

于 2012-07-31T18:42:20.693 に答える
0

申し訳ありませんが、「//非常に長いことをする」を見逃しました。長いアクションの最後に特定の順序で実行する必要がある特別なアクションがある場合は、そのコードを3つのスレッドの結合の背後に配置するだけです。

このアクションをその特定のスレッドで実行する必要がある場合は、ミューテックスと条件変数で保護された共有カウンターを使用して、このカウンターが変更されたことを通知できます。カウンターを変更するときは、特定のスレッドをウェイクアップする必要があるため、すべてのウェイターに通知する必要があります。関数の最後で、関数はカウンターがスレッド固有の値を持つのを待ちます。最初のスレッドは初期値を待機し、そのアクションを実行して、カウンターをインクリメントします。2番目のスレッドは、カウンターが2番目の値になるのを待っています。

于 2012-07-31T18:45:31.080 に答える
-1

そのスレッドの長いプロセスがディスパッチされた順序で完了したときに、プッシュバックを「同期化」するコールバックを作成できます。

ちなみに、マルチスレッドの世界でpush_backが必要な場合は、ベクトルではなくリストを使用します。リストは、削除される要素以外のすべてのイテレーターを保持します...

于 2012-07-31T18:42:15.303 に答える
-1

書かれているように、挿入は任意に順序付けることができます。希望する注文を確実に行うには、基本的に、チケット番号が要求されるまでスレッドがスリープ/スピンするチケットシステムが必要です。大まかに言うと、各スレッドに追加の情報(チケット番号)を渡し、要求されたチケットIDであるグローバル共有値を持ち、スレッドコードには挿入が実行されないようにするコードが含まれていることを意味しますグローバルIDがローカル番号と等しくなるまで。

于 2012-07-31T18:42:47.650 に答える