当多个线程同时访问数据时,必须同步访问以防止数据完整性问题。局部变量是否需要同步?
答案 0 :(得分:5)
当多个线程同时访问数据时,必须同步访问以防止数据完整性问题。是否需要同步局部变量?
问题表明你以错误的方式思考问题。一旦你开始正确地思考问题,你就不再需要提问了。
首先删除问题中的错误。
当多个线程同时访问数据时,必须同步访问以防止数据完整性问题。
这是一种常见的特征,但它太巧妙了,因为它太弱了。描述情况的正确方法是:
所以不是:
当多个线程同时访问数据时,必须同步访问以防止数据完整性问题。
在多线程代码的疯狂世界中,可能会出现与同时访问或数据完整性无关的问题。相反,更准确地说:
当多个线程对内存执行读写操作时,可以观察到这些读写操作是意外顺序,并且在意外时间违反程序不变量,除非使用同步原语将有效重新排序限制为那些保留程序不变量。
现在你的问题的答案很明确:
是否需要同步局部变量?
如果必须遵守关于特殊事件的特定顺序的局部变量的读写,以保留程序不变量,并且C#规范尚未保证所需的顺序然后,就像所有从内存中读取和写入一样,它们必须使用同步原语来实现所需的顺序。
不要陷入其他一些答案所说的“当地人在堆栈上”的陷阱。 - 他们不一定是短期游泳池!只有在短期池的生命周期短于方法的激活时才会分配本地,而当方法激活在逻辑上形成堆栈时。作为lambda的封闭本地的本地生命周期很长,迭代器块或异步方法中的locals在激活不形成堆栈的方法中。
此外,谁在乎呢? 可以使用不安全的代码在线程之间共享堆栈内存。
也不要陷入认为某些当地人是真正的当地人和#34;还有一些是假冒的当地人"。本地的定义特征是其名称具有本地范围,而不是它具有短生存期。不保证当地人在C#中的寿命很短。
以下是一些可以在多个线程上访问本地的方法:
IEnumerator
。请注意,这几乎肯定会死得很厉害;在这些条件下,迭代器块的设计并不安全。答案 1 :(得分:0)
是的,如果并行访问:
private List<int> GetInts()
{
var res = new List<int>();
Parallel.For(0,100, i=>
{
lock(res)
{
res.Add(i);
}
});
return res;
}