以下代码为n和v生成随机值。在没有得到适当保护的情况下,n是随机的并不奇怪。但是假设v应该最终为0.我的代码中有什么问题吗?或者有人能为我解释一下吗?感谢。
我正在研究x86架构的4核服务器。 uname如下。
Linux 2.6.9-22.ELsmp#1 SMP Mon Sep 19 18:00:54 EDT 2005 x86_64 x86_64 x86_64 GNU / Linux
#include <stdio.h>
#include <pthread.h>
#include <asm-x86_64/atomic.h>
int n = 0;
atomic_t v;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#define LOOP 10000
void* foo(void *p)
{
int i = 0;
for(i = 0; i < LOOP; i++) {
// pthread_mutex_lock(&mutex);
++n;
--n;
atomic_inc(&v);
atomic_dec(&v);
// pthread_mutex_unlock(&mutex);
}
return NULL;
}
#define COUNT 50
int main(int argc, char **argv)
{
int i;
pthread_t pids[COUNT];
pthread_attr_t attr;
pthread_attr_init(&attr);
atomic_set(&v, 0);
for(i = 0; i < COUNT; i++) {
pthread_create(&pids[i], &attr, foo, NULL);
}
for(i = 0; i < COUNT; i++) {
pthread_join(pids[i], NULL);
}
printf("%d\n", n);
printf("%d\n", v);
return 0;
}
答案 0 :(得分:6)
你应该使用gcc内置函数(参见。this)这很好用,也适用于icc。
int a;
__sync_fetch_and_add(&a, 1); // atomic a++
请注意,在没有锁定的情况下修改变量时,应该了解缓存一致性问题。
答案 1 :(得分:4)
答案 2 :(得分:3)
我们可以看一下代码的汇编输出(gcc -E,我认为)。甚至认为uname表明它是SMP感知的,这并不一定意味着它是用CONFIG_SMP编译的。
如果没有这个,汇编程序代码输出没有lock
前缀,你可以发现你的核心相互干扰。
但是我会使用pthread功能,因为它们可以在更多平台上移植。
答案 3 :(得分:0)
Linux内核atomic.h
在userland中无法使用,从来没有。在x86上,其中一些可能会起作用,因为x86是相当友好的体系结构,但在某些平台上,它很大程度上依赖于能够执行特权操作(较旧的臂)或至少能够禁用抢占(较旧的arm和sparc)至少),在userland中不是这样的情况!