6

POSIXによると、

現在ブロックされているスレッドがない初期化された条件変数を破棄しても安全です。

さらに、条件変数でブロックされた 1 つまたはすべてのスレッドのブロックを解除するために、シグナルおよびブロードキャスト操作が指定されます。

したがって、次の形式の自己同期破壊が有効であるように思われます。つまり、 を呼び出しpthread_cond_destroyます。

  1. cond var.
  2. 待機中のスレッドまたはブロードキャスト スレッドのいずれかで、ブロードキャストが成功した直後。

もちろん、これはそれ以上のウェイターが到着せず、その後さらにシグナルが実行されないことを前提としていますpthread_cond_destroy

これらの状況で破壊が有効であるというのは正しいですか? また、条件変数で注意すべき他の自己同期破壊シナリオはありますか?

最後に、破棄せずに共有マッピングのマッピングを解除することが理にかなっているプロセス共有の cond 変数の場合、マッピング解除が同じコンテキストで有効であると期待するのは合理的ですか? (アドレス空間) は同じマッピングを使用しており、上記のコンテキストのいずれかでマッピングを解除したいですか?

4

3 に答える 3

2

いいえ、あなたの仮定のほとんどが正しいとは思いません。pthread_cond_signalorから戻るpthread_cond_broadcastことは、いずれかのスレッドがまだ条件変数から「ブロック解除」されていること、つまり、ブロック解除されるスレッドがその変数にアクセスする必要がなくなったことを示しているわけではありません。標準では、「ブロックを解除する必要がある」とのみ記載されており、「この呼び出しから正常に戻った場合にブロックが解除される」とは記載されていません。後者は実装が非常に制限されるため、これをそのまま定式化するのにはおそらく十分な理由があります。

つまり、唯一のブロックされたスレッドまたはプロセスが起動後に状態を破棄する場合です。

于 2011-09-29T18:17:40.410 に答える
0

この言語の解釈 (および Open POSIX テスト スイートの解釈) には同意しますが、使用法は実装に依存します。そのため、主な実装のいくつかを簡単にまとめます。

安全

  • nptl -条件でまだブロックされているスレッドがある場合にpthread_cond_destroy()返されます。EBUSY破壊の責任は、ブロックされていないことによって通知されたスレッドに渡されます。
  • pthread-win32 MSVC -条件でブロックされているスレッドがまだある場合にpthread_cond_destroy()返されます。EBUSY通知されているがブロック解除されていないスレッドはpthread_cond_destroy()、アプリケーションに制御を返す前に実行されます。

安全だがブロックする

  • Darwin libc-391 -条件でまだブロックされているスレッドがある場合にpthread_cond_destroy()戻ります。EBUSYブロックされているがシグナル状態のスレッドに対する準備は行われません。
  • Dietlibc 0.27 -条件でまだブロックされているスレッドがある場合にpthread_cond_destroy()戻ります。EBUSYブロックされているがシグナル状態のスレッドに対する準備は行われません。

おそらく安全ではない

  • Android__futex_wake_ex -同期するためのシステム実装に依存します。したがってpthread_cond_broadcast()、すべてのスレッドが目覚めるまでブロックする必要があります (ただし、ミューテックスは解放されません)。
  • さまざまな win32 実装PulseEvent()- 多くは実装する関数に依存していますpthread_cond_broadcast()。これには既知の競合状態があります

オッドボール

  • OSKit 0.9 - 安全ですが、まだ参照されている条件変数で呼び出されると戻りEINVALますpthread_cond_destroy()

編集

コメントを正しく読んだ場合の主な問題は、条件変数が返される前にブロックが解除されたpthread_cond_wait()にアクセスできるかどうかです。答えはイエスです。ルーチンは、その引数が有効なままであると想定しています。

これは、ブロードキャスト後に、条件変数が他のスレッドによって使用されていないとスレッドが想定できないことを意味します。

を呼び出した場合pthread_cond_broadcast()、関連するミューテックス ロックは取得されません。条件変数を待機しているスレッドは順次実行され、それぞれが関連するミューテックスを順次取得します。ウェイターが相互にブロックする可能性があるため、ウェイターがまだpthread_cond_wait()ミューテックスでブロックされている間 (ただし、条件を待機していない)、ブロードキャスト スレッドが実行を続ける可能性があります。


編集 2

[...]破壊が有効であるのと同じコンテキストでマッピング解除が有効であると期待するのは合理的ですか?

編集 1 の理由に基づくと、これは合理的な期待ではないと思います。pthread_cond_destroy()

于 2011-10-14T20:16:28.233 に答える
0

コメント (未回答):

それはあなたが念頭に置いていることですか?

グローバル:

// m によって保護されています:
pthread_mutex_t m;
pthread_cond_t c;
bool about_to_pthread_cond_wait = false;
bool condition_waited_on = false;

スレッド A:

pthread_mutex_lock (&​​m);
{ // ロックされた領域
    about_to_pthread_cond_wait = true;
    while (condition_waited_on) {
        // pthread_cond_wait (&m, &c) は次のように分解されます:
        __pthread_mutex_cond_wait_then_unlock (&​​m, &c);
            // ロックされていない領域
        pthread_mutex_lock (&​​m);
    }
}
pthread_mutex_unlock (&​​m);

スレッド B:

for (bool break_loop = false; !break_loop;) {
    pthread_mutex_lock (&​​m);
    { // ロックされた領域
        condition_waited_on = true;

        if (about_to_pthread_cond_wait) {
            pthread_cond_signal (&c);
            pthread_cond_destroy (&c);
            break_loop = true;
        }
    }
    pthread_mutex_unlock (&​​m);

    pthread_yield ();
}

編集:

私はそうすると思いpthread_cond_wait (&m, &c);ます:

__pthread_mutex_cond_wait_then_unlock (&​​m, &c);
pthread_mutex_lock (&​​m);

__pthread_mutex_cond_wait_then_unlockCVへの信号を監視し、ミューテックスのロックを解除してからスリープ状態になります。

CV に内部ミューテックスが__pthread_mutex_cond_wait_then_unlockあり、内部pthread_cond_signalでロックする必要がある場合は、次のように仮定__pthread_mutex_cond_wait_then_unlockします。

pthread_mutex_lock (&​​c.int_mutex);
{ // c.int_state のロックされた領域
    __register_wakeup_cond (&c.int_state);
    pthread_mutex_unlock (&​​m);
}
pthread_mutex_unlock (&​​c.int_mutex);
// c.int_state にはもう触れません

__sleep_until_registered_wakeups ();

そして、次のことをpthread_cond_signal行います:

pthread_mutex_lock (&​​c.int_mutex);
{ // CV 内部状態の領域をロック
    __wakeup_registered (&c.int_state);
}
pthread_mutex_unlock (&​​c.int_mutex);

Thenは の使用が終了したpthread_cond_destroy後にのみ呼び出されます。__pthread_mutex_cond_wait_then_unlockc.int_state

于 2011-10-15T14:04:34.963 に答える