4

sを使用して、あるスレッドでのメモリ書き込みが他のスレッドでいつ表示されるかについての保証はありますpthreadか?

Javaと比較すると、Java言語仕様には、ポータブルなマルチスレッドJavaコードの記述を可能にするロックとメモリの相互作用を指定するセクションがあります。

対応するpthreadの仕様はありますか?

もちろん、いつでも共有データを揮発性にすることができますが、それは私が求めていることではありません。

これがプラットフォームに依存する場合、事実上の標準はありますか?または、別のスレッドライブラリを使用する必要がありますか?

4

2 に答える 2

8

POSIXは、4.11メモリ同期でメモリモデルを指定します。

アプリケーションは、複数の制御スレッド(スレッドまたはプロセス)による任意のメモリ位置へのアクセスが制限され、別の制御スレッドがメモリ位置を変更している間、制御スレッドがメモリ位置を読み取ったり変更したりできないようにする必要があります。このようなアクセスは、スレッドの実行を同期し、他のスレッドに関してメモリを同期する関数を使用して制限されます。次の関数は、他のスレッドに関してメモリを同期します。

  • フォーク()
  • pthread_barrier_wait()
  • pthread_cond_broadcast()
  • pthread_cond_signal()
  • pthread_cond_timedwait()
  • pthread_cond_wait()
  • pthread_create()
  • pthread_join()
  • pthread_mutex_lock()
  • pthread_mutex_timedlock()
  • pthread_mutex_trylock()
  • pthread_mutex_unlock()
  • pthread_spin_lock()
  • pthread_spin_trylock()
  • pthread_spin_unlock()
  • pthread_rwlock_rdlock()
  • pthread_rwlock_timedrdlock()
  • pthread_rwlock_timedwrlock()
  • pthread_rwlock_tryrdlock()
  • pthread_rwlock_trywrlock()
  • pthread_rwlock_unlock()
  • pthread_rwlock_wrlock()
  • sem_post()
  • sem_timedwait()
  • sem_trywait()
  • sem_wait()
  • semctl()
  • semop()
  • 待つ()
  • waitpid()

pthread_once()関数は、指定されたpthread_once_tオブジェクトの各スレッドでの最初の呼び出しのメモリを同期します。

PTHREAD_MUTEX_RECURSIVEでミューテックスタイプがあり、呼び出し元のスレッドがすでにミューテックスを所有している場合、pthread_mutex_lock()関数はメモリを同期する必要はありません。ミューテックスタイプがPTHREAD_MUTEX_RECURSIVEであり、ミューテックスのロックカウントが1より大きい場合、pthread_mutex_unlock()関数はメモリを同期する必要はありません。

特に明記されていない限り、上記の関数のいずれかがエラーを返した場合、呼び出しによってメモリが同期されるかどうかは指定されていません。

アプリケーションでは、複数の制御スレッドがメモリ位置を同時に読み取ることができる場合があります。

于 2012-10-07T23:46:27.310 に答える
0

POSIX スレッドがそのような保証を提供していることは知りません。スレッド共有オブジェクトへのアトミック アクセスのモデルがありません。POSIX スレッドの場合、変更の可視性を確保できる唯一の保証は、ある種のロックを使用することです。

最新の C、C11 (およびおそらく C++11) には、この種の質問に対するモデルがあります。スレッドとアトミック (フェンスとそのすべて) があり、あるスレッドによって行われた変更が別のスレッドから見えると想定する場合に、正確なルールを提供します。

C11 のスレッド インターフェイスは、POSIX スレッドの簡易バージョンであり、機能が少なくなっています。残念ながら、そのスレッド インターフェイスのセマンティクスの仕様はまだかなり曖昧であり、基本的に多くの場所でセマンティクスが欠落しています。しかし、C11 インターフェースと POSIX スレッドのセマンティクスを組み合わせることで、最新のシステムで物事がどのように機能するかをよく理解できます。

編集:したがって、メモリ同期を保証したい場合は、POSIXが提供するロックインターフェイスを使用するか、アトミック操作を使用してください。最新のすべてのコンパイラには、これらを提供する拡張機能があり、gcc およびファミリ (icc、opencc、clang) には一連のビルトインなどがあり__sync...ます。Clang の最新バージョンでは、新しい C11 機能も既にサポートされてい_Atomicます。に近い他のコンパイラのインターフェイスを提供するラッパーも利用できます_Atomic

于 2012-10-07T20:54:43.417 に答える