单个变量的读写是否是原子的?

今天买了本《Effective java》,我头儿拿去看,然后来问我,书里说,java对单个变量的读写操作是原子的,是什么意思?然后我们就讨论,如果是C/C++,只是多线程对单个int变量进行读写操作,是否需要加锁?这个读写操作是原子的吗?

这是一段代码,试图自己从软件层实现mutex:

/** @param me 0或者1 */ 
void mut_excl(int me ) { 
    static int loser; 
    static int interested[2] = {0, 0}; 
    int other=1 - me; 
    interested[me] = 1; 
    loser = me; 
    while (loser == me && interested[other]); 
    /* critical section */ 
    interested[me] = 0; 
}

它在有些CPU上是好使的,但是有些CPU则不是。

一个更极端的例子。

static char* p=NULL;
线程A执行p=strdup(“hello”);
线程B执行if(p!=NULL) std::cout<<p<<std::endl;

在极端情况下,线程B看到p被赋值了,但是去读它指向的那段内存时,读到的却是旧的数据。原因是CPU缓存向系统总线的写入顺序,并不一定严格按照CPU向缓存的写入顺序。

不过我在Intel的手册中倒是看到了这么一句话:”Writes by a single processor are observed in the same order by all processors.”这一点是我很确定的,但是我不知道为什么java在讲DCLP的时候会重新把这个拿出来说事儿。也许是因为并不是所有的CPU都是intel产的。

另外,即便是单纯的读写操作。假如是一个int,但是这个int未能按照4字节的边界对齐,那么多线程写入的结果是难以预料的。

(困了,先睡,以后再说)

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥