普通的int访问器中的关键部分实际上做了什么有用的事情吗?
int GetFoo()
{
CriticalSection(crit_id);
return foo;
}
void SetFoo(int value)
{
CriticalSection(crit_id);
foo = value;
}
两个线程是否有可能同时尝试读写foo?除非整数一次写入整数,否则我会想'不',在这种情况下我可以看到它的使用。但是我会有现代cpus在一个原子动作中读/写整数...
答案 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架构上不是线程安全的。