日期:2014-05-16  浏览次数:20837 次

多线程全局变量lock的问题
一个全局变量,4个线程访问,其中2个线程有写操作;如果我只在写操作线程里对变量进行互斥保护,在另外2个线程不保护,会不会有问题?如果变量类型是char和int或者long,会不会有区别?我的平台是arm9,32位;
我感觉对于int型数据,应该没有问题,别的型数据有可能会出错,但是几率比较小,如果读线程里出错不是致命错误的话,从编程的角度是不是可以容忍这种错误?
我目前的做法是将所有全局变量聚合在一起进行互斥,无论读写都是这样,虽然不会出错,但是我感觉这样效率太低了,尤其是需要及时访问、对时间要求比较苛刻的场合

------解决方案--------------------
关键在于你的数据之间的一致性要求。

如果只char和int的变量,那么访问时不会有什么问题的,
如果多个变量时独立的,甚至于写都不需要保护。
------解决方案--------------------
1.int变量读写是否是原子操作,是平台相关的,可以看内核相应平台的atomic.h中对atomic_set()和atomic_read()的定义,如果仅是一条汇编指令或者一个“=”赋值语句,那么对int型读写就是原子的;
2.2个线程访问某个全局变量,如果读写int型变量是原子操作,就可以不用保护,一读一写(写操作仅限于赋值,如果自加自减等就可能不是原子操作了),最好用volatile声明,防止被编译器优化;
3.如果多线程读写数据,而读数据的频率又远大于写数据的频率,使用读写锁保护比较好。由于读锁是共享的,相比互斥锁,程序并发性会好很多。
------解决方案--------------------
你可以分析一下你的代码,看看是否用原子操作可以达到要求,而免去锁操作。

你说的情况看上去很简单,但是,实际上与一些体系结构相关性太大,或者说某些情况下是不可以的。

但又并不代表你所面对的情况是不可以的。但是,如果原子操作可以应用在你的场景下,那任何体系下,都是可以的。
------解决方案--------------------

读:如果对数据不需要实时准确的,那么读操作我觉得不需要加锁
写:如果不是原子的,赋值应该没有问题,但是自增、自减是不行的,因为对于非原子的操作,需要将数据从内存读到寄存器上,改完值,再写回回内存,这样自增、自减就会出错。