0

プロセス間通信モジュール(プロセスAとプロセスB)をプログラミングしています。

プロセスAが特定のアクションを終了するとすぐにBの通信スレッドを実行(ロック解除)できる方法はありますか?つまり、Bがポーリングを実行せず、Aがアクションを終了した後にBが待機しすぎないということですか?

これらの問題を管理するコンセプト/モデル/デザインパターンはどれですか?(プロセス間同期よりも正確なもの)。どのライブラリ/メソッドをお勧めしますか?

ありがとう。

編集:私は3つの主要なOSのそれぞれに適した方法を探しています:Ms Windows、Apple Mac OS X、GNU/Linux。

4

5 に答える 5

2

これはかなり大変な作業です:

Unix OS の場合、以下を使用できます。

  • setpshared 引数を使用した pthread 条件とミューテックス。

    注: Linux 2.6、Solaris では十分にサポートされていますが、FreeBSD と Cygwin はサポートされていません (Mac OS X については知りません)。

  • Unix の場合、名前付きセマフォも使用できますが、それらのサポートレベルはわかりません

  • Windowsの場合、いくつかのイベントがあります...

これは、特に IPC にとっては大変な仕事です...

したがって、移植可能なものが必要な場合は、条件とミューテックスを持つ Boost.Interprocess を確認することをお勧めします...

ただし、サポートするすべての OS ですべての機能がサポートされていることを確認してください。

Boost.Interprocess に関する注意事項

Boost.Interprosess は、常にサポートされているとは限らない pthread_* 関数を使用し、エミュレーションに失敗するため、使用する必要がある各 Unix OS のサポート レベルを慎重に確認してください。そのようなエミュレーションの品質を確認してください。

また、これが Windows でどのように機能するかを確認してください。Win32 API に「共有メモリ内」のミューテックスがないことがわかっている限り、通常は名前付きオブジェクトを使用する必要があるため、何がサポートされているか、どのようにサポートされているかを確認してください。

于 2009-08-17T07:34:11.420 に答える
1

編集: IPC 用に改訂された、スレッド間同期が必要だと誤って考えました

待機可能なイベントのようなものが必要だと思います。

Windows ではCreateEvent()、 を使用して、名前付きの自動リセット イベントを作成 (または既存のものを取得) できます。

プロセス A が処理を完了するとSetEvent()、 を呼び出す必要があります。一方、プロセス B は、WaitForSingleObject()完了 (またはタイムアウト) までスリープするように呼び出します。

または、 によって作成され、0 に初期化されたセマフォを使用することもできます。CreateSemaphore()プロセス A は を呼び出して完了を通知しReleaseSemaphore()、プロセス B は再びWaitForSingleObject()完了を待ちます。

Linux および OS X では、セマフォを使用して同様の効果を得ることができます。sem_open()名前付きセマフォを作成するために使用します。初期値は 0 です。

プロセス A が完了するとsem_post()、セマフォをインクリメントするために呼び出す必要があり、プロセス B はsem_wait()完了するまでスリープするために呼び出す必要があります。

: セマフォ メソッドを使用すると、複数の完了を通知できる場合があります。Windows で最大カウントを設定するか、現在の sem 値の健全性をチェックして、これを処理する必要があります。sem_getvalue()


条件変数はあなたがやろうとしていることに合っていると思います。Linux と OSX で動作するサンプルを次に示します。

#include <pthread.h>
/* no error checking, quick and dirty sample */
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
int a_done = 0;

void init(void)
{
    pthread_mutex_init(&g_mutex, NULL);
    pthread_cond_init(&g_cond, NULL);
}

void thread_a(void *arg)
{
    /* do something here... */
    pthread_mutex_lock(&g_mutex);
    a_done = 1;
    pthread_cond_signal(&g_cond);
    pthread_mutex_unlock(&g_mutex);
}

void thread_b(void *arg)
{
    /* wait for a to complete */
    pthread_mutex_lock(&g_mutex);
    while (!a_done)
        pthread_cond_wait(&g_cond, &g_mutex);
    a_done = 0;
    pthread_mutex_unlock(&g_mutex);
}

Windows ではpthreads-win32、または Vista ではネイティブの条件変数を使用できます。詳細については、MSDN 条件変数ページを参照してください。

参考文献:

于 2009-08-05T10:01:39.967 に答える
0

OSがシグナルをサポートしている場合は、シグナルハンドラーからミューテックスのロックを解除し、タスクが完了するとすぐにプロセスAからシグナルを送信できます。

プロセスBはミューテックスまたは他の同期ツールを待機し、Aは何でも処理し、終了するとたとえば信号USR1を送信し、プロセスBのUSR1ハンドラーは対応する同期ツールのロックを解除します。

于 2009-08-05T08:59:18.440 に答える
0

最も一般的なのは、select()/ poll()を使用することです。利用可能な入力がある場合、両方ともいくつかのファイル記述子をチェックできます。どちらもタイムアウトパラメータを受け取ります。これにより、100%のCPUを消費する可能性のあるビジーウェイトを防ぐことができます。これは、中小規模のアプリケーションに非常に適したソリューションです。

別のアプローチは、別のスレッドでポーリングを行うことです。

大きなアプリケーションを開発する場合は、 ACEフレームワークまたは ブーストに目を向ける価値があります。これらのフレームワークはクロスプラットフォームソリューションであり、適切に設計され、十分にテストされています。

于 2009-08-05T09:05:47.147 に答える
0

私の意見と経験では、ポータブルで簡単な方法でこれを行う最善の方法は、ソケットを使用することです。さらに、2 つのプロセスを別のマシンに配置することもできます (必要な場合)。さらに、通信を拡張して、シンクロ以上のものを処理できます。

ポーリングしたくない場合は、ソケットで同期メッセージを待機するスレッドを使用します。ブロックする方法でソケットを読み取ります。メッセージを受信したら、標準のマルチスレッド同期を使用して同期を処理します。あなたの場合、B は A が終了するまで待機する必要があるため、プロセスでブロックする方法で読み取る必要があります。

移植可能にするには、 boostptypesなどの移植可能なソケット ライブラリを使用します。

于 2009-08-10T15:17:22.393 に答える