围绕整数getter和setter的关键部分是多余的?

时间:2010-06-17 15:00:58

标签: c++ multithreading

  

可能重复:
  Do I need to use locking with integers in c++ threads

普通的int访问器中的关键部分实际上做了什么有用的事情吗?

int GetFoo()
{
   CriticalSection(crit_id);
   return foo;
}

void SetFoo(int value)
{
   CriticalSection(crit_id);
   foo = value;
}

两个线程是否有可能同时尝试读写foo?除非整数一次写入整数,否则我会想'不',在这种情况下我可以看到它的使用。但是我会有现代cpus在一个原子动作中读/写整数...

4 个答案:

答案 0 :(得分:3)

只要您使用内存对齐的本机字长整数,读取就是原子的,可以在没有锁定的情况下完成,但写入会导致竞争条件,因此必须锁定。如果变量没有与内存对齐,则可能会导致多核/多CPU环境不一致。

答案 1 :(得分:2)

据我所知,这取决于你的拱门。一些系统读/写本机宽度整数是原子的,其他系统是

您应该研究热门编译器提供的原子内在函数。

对于gcc来说是这样的:

__sync_lock_test_and_set(&foo, value);

这会将foo原子地设置为value(它也会返回旧值,但您可以忽略它)。但是线程安全有很多选择。

答案 2 :(得分:0)

AFAIK,默认情况下,没有高级操作是原子操作。

要写一个整数,cpu必须在内存中计算其物理地址,这需要一些低级操作。你可以在中间的任何时候被踢出cpu。

也许某些语言为您提供了这种可能性,但一般而言,流行语言(如C ++)则不然。您有责任创建和维护关键部分。

某些语言(如Java)为您做了肮脏的工作,只需在定义函数时添加synchronized作为关键字。

这里有一个如何在C ++中创建关键部分的示例 http://www.codeproject.com/KB/threads/cppsyncstm.aspx

答案 3 :(得分:0)

AFAIK访问寄存器的任何内容都不是线程安全的。我有95%的积极与一个++运算符异步递增一个计数器,例如,在Pentium架构上不是线程安全的。