2016-03-30 16 views
1

以下のコードサンプルは、一度に1つのスレッドを効率的に実行できるようにします。スレッドへの参照を保持し、後で 'Thread.join'を呼び出しても同じ結果が得られます。プログラムがスレッドを独立して並行して処理し続けるのを待って、これらのスレッドをこのようにして終了させる方法は?他のいくつかのKernelオブジェクトシグナリングメカニズムが使われなければならないと私には思われます。 (要するに二次スレッドにメインスレッドを結びつけるために「参加」使用すると、他のスレッドを同時に実行できません?)複数のスレッドが完了してからC++でプログラムを終了するまでの適切な方法11

int main() { 
    while (cin) { 
     getline(cin, input_line); 
     if (input_line.length()>0) 
     { 
      thread t = thread(SomeLengthyCheck, input_line); 
      t.join(); 
     } 
    } 
} 
+0

」o11c @によって提案された例外安全なバージョンセカンダリスレッドにメインスレッドを結びつけるために 『参加』使用すると、他のスレッドを同時に実行することはできません。 ? " - その仮定は単に間違っている。ちょうど1秒間スリープする複数のスレッドを起動してください。その後、これらすべてのスレッドに参加し、全体のプログラムにかかる時間を監視します。 –

+0

@Ulrich whileループで 'thread.join'を呼び出すと、他のスレッドも起動しないので、上記のコードフラグメントを参照していました。すべてのスレッドが作成された後に結合を使用すると、完了するまで続けます(後述)。また、私はスレッドがメインスレッドが終了した後でも続行する必要がある仕様状態を理解しますが、私はそのアプローチに慣れていません。 – Gio

答えて

1

通常、スレッド配列を使用して、forループでそれらのすべてを待機します。

最終的にすべてが終了するように、注文は気にしません。

あなたが待つ必要があるスレッドの数がわからないので、あなたのスレッドスタック/キューが必要です。

int main() { 
    std::vector<std::thread> threads; 
    std::string input_line; 
    while (getline(std::cin, input_line)) { 
     if (input_line.length()>0) { 
      threads.push_back(std::thread(SomeLengthyCheck, input_line)); 
     } 
    } 
    for (auto& th : threads) th.join();  
} 

EDIT:要するに

class vthreads : std::vector<std::thread> { 
    ~vthreads() { for (auto& th : *this) th.join(); } 
}; 

int main() { 
    vthreads threads; 
    std::string input_line; 
    while (getline(std::cin, input_line)) { 
     if (input_line.length()>0) { 
      threads.push_back(std::thread(SomeLengthyCheck, input_line)); 
     } 
    } 
} 
+1

これは例外ではありません。自動的に呼び出されるデストラクタに '.join'を呼び出す方がよいでしょう。 – o11c

+0

@ o11c良いキャッチは、答えにそれを加えました。 – xvan

0

私は、Linuxとの専門家ではないが、私は、スレッドが「mainに添付されていると思いますそのため、メインスレッドの非同期的に動作する任意のスレッドが、メインでは単にreturn-ingにosを持ちますプロセスとすべての子スレッドを閉じます。

は、他の私は、呼び出し元の関数が、これはグローバル変数で発生するときは、メインプロセスにシグナルができ囲む {}

後に終了すると、スレッドが終了しますと信じています。

また、私はあなたが参加について混乱していると思います。 Joinは、非同期スレッド(関数)を本質的に同期させるために、結合されるスレッドが終了するまで呼び出しスレッドを停止させることを強制します。

+0

親プロセスのスレッドが同じメモリリソースを共有するため、グローバル変数が機能するはずです。 –

+0

この動作は、LinuxではなくC++標準で定義されています。この標準では、 'std :: thread'はデストラクタ呼び出しの前にデタッチまたは結合されなければならないとも言われています。 'std :: thread'が作成されたスコープを離れるだけで、どちらも実行されず、' abort() 'が呼び出されます。 –

関連する問題