CentOS プラットフォームで GCC を使用している場合は、__atomic
を使用できます。 組み込み関数。
特に興味深いのは、次の関数です:
<ブロック引用>
— 組み込み関数:bool __atomic_always_lock_free (size_t size, void *ptr)
この組み込み関数は、オブジェクトが size
の場合に true を返します バイトは常に、ターゲット アーキテクチャのロック フリー アトミック命令を生成します。 size
コンパイル時の定数に解決する必要があり、結果もコンパイル時の定数に解決されます。
ptr
アラインメントを決定するために使用できるオブジェクトへのオプションのポインタです。 0
の値 は、一般的なアライメントを使用する必要があることを示しています。コンパイラは、このパラメーターを無視することもあります。
if (_atomic_always_lock_free (sizeof (long long), 0))
C11 アトミック プリミティブ
http://en.cppreference.com/w/c/language/atomic
_Atomic const int * p1; // p is a pointer to an atomic const int
const atomic_int * p2; // same
const _Atomic(int) * p3; // same
glibc 2.28 で追加されました。ソースから glibc をコンパイルすることにより、Ubuntu 18.04 (glibc 2.27) でテスト済み:単一のホストで複数の glibc ライブラリを実行後、Ubuntu 20.04、glibc 2.31 でもテスト済み。
例:https://en.cppreference.com/w/c/language/atomic
main.c
#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>
atomic_int acnt;
int cnt;
int f(void* thr_data)
{
(void)thr_data;
for(int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
// for this example, relaxed memory order is sufficient, e.g.
// atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
}
return 0;
}
int main(void)
{
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
}
コンパイルして実行:
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c -pthread
./main.out
可能な出力:
The atomic counter is 10000
The non-atomic counter is 8644
非アトミック カウンターは、非アトミック変数へのスレッド間で際どいアクセスのため、アトミック カウンターよりも小さい可能性が非常に高いです。
逆アセンブリ分析:プレーン C でスレッドを開始するにはどうすればよいですか?