web-dev-qa-db-ja.com

スレッド間のC ++通信

それぞれが異なるスレッドで異なるプログラムを開き、CreateProcessを使用してそれに関する情報を実行/保持するクラスがいくつかあります(これを行うためのよりC++指向の方法がある場合は、私に知らせてください-私は見ました)。

一部のクラスは、実行中の他のプログラムのいずれかに依存しています。つまり、Aが停止した場合、Bも停止する必要があります。私はしばらく前にこのコードを作成し、私の解決策は、さまざまなプログラムを実行する静的関数と、「状態」を保持する静的メンバー変数を持つクラスを作成することでした。私もCreateThreadを使用していました。

振り返ってみると、この方法は...壊れやすくてぎこちない見た目でした。そのような「静的クラス」の使用が良い習慣であるかどうかはわかりません(特に、状態メンバー変数の初期化がいかに厄介であることを思い出してください)。おそらく、各クラスに独自の実行関数を含めたいと思います。しかし、私が考えている問題は、Aが不自然に停止したかどうかをクラスBにどのように知らせるかです。彼らはまだお互いの状態を認識する方法を知る必要があります。このリワークではstd::threadを使用したいので、マルチスレッドの経験はほとんどまたはまったくないことに注意してください。助けてくれてありがとう。

12
2c2c

マルチプロセスアプリケーションでは、パイプ/ファイルを使用して、あるプロセスから別のプロセスに情報を送信します(または子プロセスの戻り値でさえも)。共有メモリを試すこともできますが、少し難しい場合があります(必要に応じてBoost.Interprocessを調べてください)。

マルチスレッドアプリケーションでは、基本的に同じオプションを利用できます。

  • 共有されているメモリを使用できます(アクセスを同期する場合)
  • キューを使用して、あるスレッドから別のスレッドに情報を渡すことができます(パイプなど)

本当に2つは非常に似ています。

Tony Hoareの原則に従って、一般的には共有によって共有し、共有によって通信しないにする必要があります。これは、共有メモリへのキュー/パイプの特権を意味します。ただし、ブールフラグの場合は、共有メモリを簡単に配置できます。

void do_a(std::atomic_bool& done) {
     // do things
     done = true;
}

int main() {
    std::atomic_bool done = false;

    auto a = std::async(do_a, done);

    auto b = std::async([](std::atomic_bool& done) {
        while (not done) {
            std::cout << "still not done" << std::endl;
            sleep(1);
        }
    });

    // other stuff in parallel.
}

そしてもちろん、このフラグをstd::shared_ptr参照がぶら下がるリスクを回避するため。

8
Matthieu M.