gpt4 book ai didi

c - 为什么 gcc(3.4.5) 中的用户空间 atomic_t 不起作用

转载 作者:太空狗 更新时间:2023-10-29 15:42:26 24 4
gpt4 key购买 nike

最近工作中,想在多线程程序中实现一个计数器。我发现在我的 GCC(3.4.5) 中有一个名为 atomic_t 的用户空间数据类型。但它似乎不是真正的原子。

我在一台 12 核的 x86_64 机器上测试了 atomic_inc()/atomic_read(),linux 内核是 2.6.9。

这是演示。我添加了 pthread_cond_t 和 pthread_cond_broadcast 来增加并发度。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <pthread.h>
#include <asm/atomic.h>

atomic_t atomic_count;
pthread_cond_t g_cond;
pthread_mutex_t g_mutex;

void* thread_func(void*p) {
pthread_mutex_t* lock = (pthread_mutex_t*)p;
pthread_mutex_lock(lock);
pthread_cond_wait(&g_cond, lock);
pthread_mutex_unlock(lock);

for (int i=0;i<20000;++i){
atomic_inc(&atomic_count);
}
return NULL;
}
#define THRD_NUM 15

int main() {
atomic_set(&atomic_count, 0);
pthread_cond_init(&g_cond, NULL);
pthread_mutex_init(&g_mutex, NULL);
pthread_t pid[THRD_NUM];

for (int i=0; i<THRD_NUM; i++) {
pthread_create(&pid[i], NULL, thread_func, &g_mutex);
}

sleep(3);
pthread_cond_broadcast(&g_cond);

for (int i=0; i<THRD_NUM; i++) {
pthread_join(pid[i], NULL);
}

long ans = atomic_read(&atomic_count);
printf("atomic_count:%ld \n", ans);
}

预期结果是 300000,但我们总是得到 270000+ 或 280000+。我发现 atomic_inc() 的实现是

 static __inline__ void atomic_inc(atomic_t *v)
{
__asm__ __volatile__(
LOCK "incl %0"
:"=m" (v->counter)
:"m" (v->counter));
}

根据英特尔手册,LOCK 前缀具有完全屏障的语义。这是否意味着程序的输出与指令重新排序无关?

另外,我还发现了一个有趣的现象。如果我将 THRD_NUM 设置为小于 12(我的机器的核心编号),错误的频率就会降低。我认为这可能是由上下文切换引起的。但我不知道这是怎么发生的。有人能帮我吗?谢谢!

最佳答案

LOCK 是一个宏。你确定它实际上被定义为“锁定”,因为它应该是实际做任何事情?

我很确定您正在使用仅用于内核的 header 。 “asm”下的内容不应在用户空间中使用。

关于c - 为什么 gcc(3.4.5) 中的用户空间 atomic_t 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17861335/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com