[英]Are C# arrays thread safe?
特别是
我知道如何管理线程等。我有兴趣知道这是否是线程安全的做某事的方式。
class Program
{
// bogus object
class SomeObject
{
private int value1;
private int value2;
public SomeObject(int value1, int value2)
{
this.value1 = value1;
this.value2 = value2;
}
}
static void Main(string[] args)
{
var s = new SomeObject[10];
var threads = Environment.ProcessorCount - 1;
var stp = new SmartThreadPool(1000, threads, threads);
for (var i = 0; i < 10; i++)
{
stp.QueueWorkItem(CreateElement, s, i);
}
}
static void CreateElement(SomeObject[] s, int index)
{
s[index] = new SomeObject(index, 2);
}
}
我相信如果每个线程只在数组的一个单独部分上工作,一切都会好起来的。 如果您要共享数据(即在线程之间进行通信),那么您将需要某种内存屏障来避免内存模型问题。
我相信,如果你产生一堆线程,每个线程填充它自己的数组部分,然后等待所有这些线程使用Thread.Join
完成,这在屏障方面足以让你安全. 我目前没有任何支持文件,请注意......
编辑:您的示例代码是安全的。 任何时候都不会有两个线程访问同一个元素——就好像它们每个都有单独的变量一样。 但是,这本身并没有什么用处。 在某些时候,线程通常会想要共享状态——一个线程会想要读取另一个线程所写的内容。 否则,他们写入共享数组而不是写入自己的私有变量是没有意义的。 这就是您需要小心的点 - 线程之间的协调。
此类型的公共静态(在 Visual Basic 中为共享)成员是线程安全的。 不保证任何实例成员都是线程安全的。
此实现不为 Array 提供同步(线程安全)包装器; 但是,基于 Array 的 .NET Framework 类使用 SyncRoot 属性提供自己的集合同步版本。
通过集合进行枚举本质上不是线程安全的过程。 即使在同步集合时,其他线程仍然可以修改集合,这会导致枚举器抛出异常。 为了保证枚举期间的线程安全,您可以在整个枚举期间锁定集合或捕获其他线程所做更改导致的异常。
所以不,它们不是线程安全的。
通常,当一个集合被称为“非线程安全”时,这意味着并发访问可能会在内部失败(例如,读取 List<T> 的第一个元素是不安全的,而另一个线程在列表的末尾添加了一个元素:List <T> 可能会调整底层数组的大小,并且在将数据复制到新数组之前,读取访问可能会转到新数组)。
这种错误对于数组是不可能的,因为数组是固定大小的并且没有这样的“结构变化”。 一个包含三个元素的数组与三个变量的线程安全性差不多。
C# 规范对此没有任何说明; 但很明显,如果您了解 IL 并阅读 CLI 规范 - 您可以获得对数组内元素的托管引用(如用于 C#“ref”参数的引用),然后对其执行正常和易失性加载和存储。 CLI 规范描述了此类加载和存储的线程安全保证(例如元素 <=32 位的原子性)
因此,如果我正确理解您的问题,您想使用不同的线程填充数组,但只会分配给每个数组元素一次? 如果是这样,那是完全线程安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.