3

コードの大部分を調べてみると、glib の g_atomic_* 関数が期待どおりに動作していないことに気付き、次の簡単な例を書きました。

#include <stdlib.h>
#include "glib.h"
#include "pthread.h"
#include "stdio.h"

void *set_foo(void *ptr) {
  g_atomic_int_set(((int*)ptr), 42);
  return NULL;
}

int main(void) {
  int foo = 0;
  pthread_t other;

  if (pthread_create(&other, NULL, set_foo, &foo)== 0) {
    pthread_join(other, NULL);
    printf("Got %d\n", g_atomic_int_get(&foo));
  } else {
    printf("Thread did not run\n");
    exit(1);
  }
}

これを GCC の '-E' オプション (前処理後に停止) でコンパイルすると、g_atomic_int_get(&foo) の呼び出しが次のようになっていることに気付きました。

(*(&foo))

g_atomic_int_set(((int*)ptr), 42) は次のようになりました。

((void) (*(((int*)ptr)) = (42)))

単純な (スレッドセーフでない) 割り当てだけでなく、アトミックな比較操作とスワップ操作を想定していたことは明らかです。私は何を間違っていますか?

参考までに、私のコンパイルコマンドは次のようになります。

gcc -m64 -E -o foo.E `pkg-config --cflags glib-2.0` -O0 -g foo.c
4

1 に答える 1

2

現在使用しているアーキテクチャでは、アトミックな整数の set/get 操作にメモリ バリアは必要ないため、変換は有効です。

定義されている場所は次のとおりです。http://git.gnome.org/browse/glib/tree/glib/gatomic.h#n60

そうしないと、アトミック操作ごとにグローバルミューテックスをロックする必要があるため、これは良いことです。

于 2011-04-08T21:06:50.127 に答える