Gar*_*ary 51 c# arrays multithreading thread-safety
特别是
我知道如何管理线程等.我很想知道这是否是线程安全的做事方式.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 44
我相信如果每个线程只在阵列的一个单独部分上工作,那么一切都会很好.如果您要共享数据(即在线程之间进行通信),那么您将需要某种内存屏障来避免内存模型问题.
我相信如果你产生了一堆线程,每个线程都会填充它自己的数组部分,然后等待所有这些线程完成使用Thread.Join,这样做就足以保证你的安全.我暂时没有任何支持文件,请注意......
编辑:您的示例代码是安全的.两个线程在任何时候都不会访问同一个元素 - 就像它们每个都有单独的变量一样.但是,这本身并不常用.在某些时候,线程通常会想要共享状态 - 一个线程将要读取另一个线程所写的内容.否则,他们写入共享数组而不是写入自己的私有变量是没有意义的.这就是你需要小心的点 - 线程之间的协调.
Jor*_*ren 25
此类型的公共静态(在Visual Basic中为Shared)成员是线程安全的.任何实例成员都不保证是线程安全的.
此实现不为数组提供同步(线程安全)包装器; 但是,基于Array的.NET Framework类使用SyncRoot属性提供它们自己的集合同步版本.
枚举通过集合本质上不是线程安全的过程.即使集合是同步的,其他线程仍然可以修改集合,这会导致枚举器抛出异常.为了在枚举期间保证线程安全,您可以在整个枚举期间锁定集合,也可以捕获由其他线程所做的更改导致的异常.
所以不,他们不是线程安全的.
Dan*_*iel 14
通常,当一个集合被称为"非线程安全"时,这意味着并发访问可能在内部失败(例如,当另一个线程在列表的末尾添加一个元素时,读取List <T>的第一个元素是不安全的:列表<T>可能会调整基础数组的大小,并且在将数据复制到新数组之前,读访问可能会转到新数组.
数组不可能出现这样的错误,因为数组是固定大小的,没有这种"结构变化".具有三个元素的数组与三个变量相比没有或多或少地具有线程安全性.
C#规范没有说明这一点; 但很明显,如果您了解IL并阅读CLI规范 - 您可以获得一个托管引用(如用于C#"ref"参数的那些)到数组内的元素,然后执行常规和易失性加载并存储到它.CLI规范描述了此类加载和存储的线程安全保证(例如元素的原子性<= 32位)
因此,如果我正确地解释您的问题,您想要使用不同的线程填充数组,但是只会为每个数组元素分配一次?如果是这样,那就完全是线程安全的.
您提供的示例与Microsoft自己的C#4.0并行扩展的工作方式非常相似.
这个for循环:
for (int i = 0; i < 100; i++) {
a[i] = a[i]*a[i];
}
Run Code Online (Sandbox Code Playgroud)
变
Parallel.For(0, 100, delegate(int i) {
a[i] = a[i]*a[i];
});
Run Code Online (Sandbox Code Playgroud)
所以,是的,你的例子应该没问题.这是一篇关于C#中新的并行支持的博客文章.
| 归档时间: |
|
| 查看次数: |
31754 次 |
| 最近记录: |