C ランタイム ライブラリまたはその他のユーティリティ ライブラリでサポートされているアトミック操作 (整数のインクリメント/デクリメントなど) などを実行する関数はありますか?
はいの場合、そのような関数を使用してどの操作をアトミックにすることができますか?
このような関数を使用することは、mutex などの通常の同期プリミティブよりも有益でしょうか?
OS : Windows、Linux、Solaris、VxWorks
C ライブラリには何もありません。
__sync_fetch_and_add
Linux では、gcc がいくつかの機能を提供します -- 、などを探してください__sync_fetch_and_sub
。
InterlockedIncrement
Windows の場合は、InterlockedDecrement``,
InterlockedExchange` などを探します。Windows で gcc を使用している場合は、Linux と同じビルトインも含まれていると思います (確認していませんが)。
Solarisでは、依存します。おそらく、gcc を使用する場合、おそらく (再び) Linux と同じ組み込み機能を備えているでしょう。それ以外の場合は、ライブラリが浮かんでいますが、実際に標準化されたものはありません。
C11 では、(合理的に) 完全なアトミック操作とアトミック型のセットが追加されました。操作には、atomic_fetch_add
およびatomic_fetch_sum
(および*_explicit
、必要な順序付けモデルを指定できる同じバージョンが含まれます。デフォルトのモデルでは常に が使用されますmemory_order_seq_cst
)。fence
や などの関数もありatomic_thread_fence
ますatomic_signal_fence
。
型は、通常の整数型のそれぞれに対応します。たとえば、 にatomic_int8_t
対応しint8_t
、に対応atomic_uint_least64_t
しuint_least64_t
ます。これらはtypedef
で定義された名前<stdatomic.h>
です。既存の名前との競合を避けるために、ヘッダーを省略できます。コンパイラ自体は、実装者の名前空間で名前を使用します (たとえば、 の_Atomic_uint_least32_t
代わりにatomic_uint_least32_t
)。
サポートされているすべてのプラットフォームで、 GLib のアトミック操作を使用できます。アトミック操作が組み込まれているプラットフォーム (アセンブリ命令など) では、glib はそれらを使用します。他のプラットフォームでは、ミューテックスの使用にフォールバックします。
ミューテックスがそれらを使用して実装されていても、アトミック操作により速度が向上すると思います。ミューテックスを使用すると、少なくとも 2 つのアトミック操作 (ロックとロック解除) と実際の操作が可能になります。アトミック操作が使用可能な場合、それは単一の操作です。
「有益」は状況に応じたものです。常に、パフォーマンスは状況に依存します。このようなもののためにミューテックスを切り替えると、何か素晴らしいことが起こると期待するかもしれませんが、メリットが得られなかったり (あまり一般的でない場合)、事態を悪化させたりする可能性があります (誤って「スピンロック」を作成した場合)。 .
C ランタイム ライブラリの意味がわかりません。適切な言語、または標準ライブラリは、これを行う手段を提供しません。OS 固有のライブラリ/API を使用する必要があります。また、だまされsig_atomic_t
てはいけません。これらは一見したところ、シグナル ハンドラーのコンテキストでのみ役立つように見えるものではありません。
Windows ではInterlockedExchangeなどがあります。Linux では、glibc のアトミック マクロを使用できます。これらは移植可能です ( i486 atomic.hを参照)。他のオペレーティング システムの解決策がわかりません。
xchg
一般に、アトミック操作には x86の命令を使用できます(デュアル コア CPU でも動作します)。
2 番目の質問については、いいえ、アトミック操作を使用する方がミューテックスを使用するよりも高速になるとは思いません。たとえば、pthreads ライブラリは、非常に高速なアトミック操作を備えたミューテックスを既に実装しています。