C#和C++中的volatile关键字
volatile keyword in C# and C++
在C++中,我被教导对不同线程使用的变量(myVar)使用volatile关键字,即使在关键部分也是如此。但对于C#,我在MSDN上读到了这样一句奇怪的话:"volatile修饰符通常用于多个线程访问的字段,而不使用lock语句序列化访问。"这个短语的意思是,如果我被锁定,那么就不需要使用volatile关键字吗?如果是,那么还有一个问题:可能我必须锁定exect这个变量(myVar)?
Object a = new Object();
double i,k;
Thread1()
{
lock(a)
{
i++;// using variable i.
k++;// using variable k.
}
}
螺纹2也会这样做。i和k不易挥发是安全的吗?还是我必须这样做?:
lock(i)
{
i++;// using variable i.
}
lock(k)
{
k++;// using variable k.
}
在C++中,我被教导对不同线程使用的变量(myVar)使用volatile关键字,即使在关键部分下也是如此
谁教你这并不是在教你整个故事。C++中的Volatile不能保证读取或写入具有获取或释放语义!所有volatile的保证是编译器不会生成省略读取或无序读取和写入的代码只有Volatile不足以确保多线程中的正确语义,除非编译器对"Volatile"的含义做出一些额外的声明。
volatile修饰符通常用于多个线程访问的字段,而不使用lock语句序列化访问。"这个短语的意思是,如果我被锁定,那么就不需要使用volatile关键字吗?
正确。在C#中,volatile确实通过插入适当的半栅栏来引入获取和释放语义。由于锁引入了完整的围栏,因此在读取锁中的字段时不需要volatile。
可能是我必须锁定exect这个变量(myVar)?
所有这些代码都是完全错误的,无法回答这个问题。++在doubles上是危险的,使doubles不稳定在C#中甚至是不合法的,并且不能锁定值类型。
在标准C++中,volatile
与线程无关,尽管显然微软的编译器赋予了它一些特殊的含义。对于计数器之类的东西,请使用std::atomic<int>
;不需要单独的锁。
正确,在lock
下的C#中,您不需要使用volatile
,因为使用lock
可以确保所有线程都看到最新的值。
我同意你的看法,这在MSDN文档中并不清楚:lock
只提供对代码块的互斥访问,但除此之外,它还具有其他线程安全特性,例如确保每个线程都看到相同的值,这是lock
固有的,因为它使用内存屏障。
你的第二个问题是不可能的——你必须在引用类型上使用lock
——然而,假设你这样做了,在这两种情况下,如果所有其他对变量的读写都锁定在同一个实例上,那么你的操作都是"线程安全的",通常情况下,更细粒度的对象更好,这样你就不必让其他线程在想要更新其他东西时等待,而必须获取相同的锁,但您可能知道这些var总是一起访问的,在这种情况下,共享锁会更有效率。
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- C++中的"inline"关键字
- 如何确保C++函数在定义之前声明(如override关键字)
- 在一个读写器队列中,我可以用volatile替换原子吗
- 谷歌模拟和覆盖关键字
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- 为什么"delete"关键字不删除节点?
- 在 c++ 中正确定义"this"关键字?
- 这个额外的关键字在这个 c++ 类声明中是什么意思?
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- 了解C++中的'volatile'关键字
- C++11是否允许(不要求)volatile关键字的发布/获取语义
- C#和C++中的volatile关键字
- Volatile关键字允许访问UnitTest++中的常量结构
- 如果我在互斥锁之间声明一个变量并返回它,我需要使用volatile关键字吗?
- 在VS2012中使用'volatile'关键字的最佳实践
- 从语法的角度来看,"volatile"关键字在C++函数中有多少用法?
- 微控制器中的Volatile关键字