GLIB:g_atomic_int_get 变为 NO-OP?

发布于 2024-10-31 11:43:52 字数 927 浏览 4 评论 0原文

在一段较大的代码中,我注意到 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

In a larger piece of code, I noticed that the g_atomic_* functions in glib were not doing what I expected, so I wrote this simple example:

#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);
  }
}

When I compile this with GCC's '-E' option (stop after pre-processing), I notice that the call to g_atomic_int_get(&foo) has become:

(*(&foo))

and g_atomic_int_set(((int*)ptr), 42) has become:

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

Clearly I was expecting some atomic compare and swap operations, not just simple (thread-unsafe) assignments. What am I doing wrong?

For reference my compile command looks like this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烂人 2024-11-07 11:43:52

您所在的体系结构不需要原子整数设置/获取操作的内存屏障,因此转换是有效的。

这是它的定义位置: http://git.gnome.org/ browser/glib/tree/glib/gatomic.h#n60

这是一件好事,因为否则你需要 为每个原子操作锁定全局互斥体

The architecture you are on does not require a memory barrier for atomic integer set/get operations, so the transformation is valid.

Here's where it's defined: http://git.gnome.org/browse/glib/tree/glib/gatomic.h#n60

This is a good thing, because otherwise you'd need to lock a global mutex for every atomic operation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文