Ben*_*Ben 24 c# arrays string enumeration thread-safety
我对C#很新,所以请耐心等待.我对线程安全感有点困惑.什么时候线程安全什么东西什么时候不安全?
正在阅读从现场总是线程安全的(刚刚从一些被初始化之前读)?
//EXAMPLE
RSACryptoServiceProvider rsa = new RSACrytoServiceProvider();
rsa.FromXmlString(xmlString);
//Is this thread safe if xml String is predifined
//and this code can be called from multiple threads?
Run Code Online (Sandbox Code Playgroud)
被访问的数组或列表的对象始终是线程安全的(如果你使用一个for循环枚举)?
//EXAMPLE (a is local to thread, array and list are global)
int a = 0;
for(int i=0; i<10; i++)
{
a += array[i];
a -= list.ElementAt(i);
}
Run Code Online (Sandbox Code Playgroud)
被列举始终/曾经线程安全的?
//EXAMPLE
foreach(Object o in list)
{
//do something with o
}
Run Code Online (Sandbox Code Playgroud)
可以写入和读出一个特定的领域不断导致损坏的读取(场的一半被改变,一半仍是不变的)?
感谢您的所有答案和时间.
编辑:我的意思是如果所有线程只读取和使用(不写或更改)对象.(除了最后一个问题,显然我的意思是线程既读又写).因为我不知道普通访问或枚举是否是线程安全的.
Lou*_*nco 26
对于不同的情况,它是不同的,但一般来说,如果所有线程都在读取,则读取是安全的.如果有任何写入,读取或写入都不是安全的,除非它可以原子方式完成(在同步块内或使用原子类型).
不确定读数是否正确 - 你永远不知道幕后发生了什么 - 例如,getter可能需要在第一次使用时初始化数据(因此写入本地字段).
对于字符串,你很幸运 - 它们是不可变的,所以你所能做的就是阅读它们.对于其他类型,您在阅读时必须采取预防措施,防止其他线程发生变化.
Eri*_*ert 13
从字段读取(只读取之前初始化的东西)总是线程安全吗?
C#语言保证在3.10节中读取和写入位于单个线程上时,读取和写入始终是一致的:
数据依赖性保留在执行的线程中.也就是说,计算每个变量的值,就好像线程中的所有语句都以原始程序顺序执行一样.保留初始化排序规则.
多线程,多处理器系统中的事件不一定具有彼此相关的明确定义的一致排序. C#语言不保证一致的排序.当从另一个线程观察时,可以观察到一个线程观察到的写入序列处于完全不同的顺序,只要不涉及关键执行点即可.
因此,这个问题无法回答,因为它包含一个未定义的单词.对于多线程多处理器系统中的事件,您能否准确定义"之前"对您意味着什么?
该语言保证仅在关键执行点方面排序副作用,即使这样,在涉及异常时也不会做出任何强有力的保证.再次引用第3.10节:
执行C#程序,以便在关键执行点保留每个执行线程的副作用.副作用定义为易失性字段的读取或写入,对非易失性变量的写入,对外部资源的写入以及抛出异常.必须保留这些副作用的顺序的关键执行点是对volatile字段,锁定语句以及线程创建和终止的引用.[...]关于易失性读取和写入,保留了副作用的顺序.
此外,执行环境不需要评估表达式的一部分,如果它可以推断出不使用该表达式的值并且不产生所需的副作用(包括由调用方法或访问volatile字段引起的任何副作用).当程序执行被异步事件(例如另一个线程抛出的异常)中断时,不能保证可观察的副作用在原始程序顺序中可见.
从数组或列表访问对象始终是线程安全的(如果您使用for循环进行枚举)?
通过"线程安全",你的意思是从列表中读取时,两个线程总是会观察到一致的结果吗?如上所述,C#语言在从变量读取时对结果的观察提供非常有限的保证.在非易失性读数方面,您能否准确定义"线程安全"对您意味着什么?
枚举总是/永远是线程安全吗?
即使在单线程场景中,在枚举时修改集合也是违法的.在多线程场景中这样做肯定是不安全的.
写入和读取特定字段是否会导致读取损坏(字段的一半已更改,一半仍未更改)?
是.我引用你的第5.5节,其中说明:
以下数据类型的读取和写入是原子的:bool,char,byte,sbyte,short,ushort,uint,int,float和reference类型.此外,在先前列表中具有基础类型的枚举类型的读取和写入也是原子的.其他类型的读写,包括long,ulong,double和decimal,以及用户定义的类型,不保证是原子的.除了为此目的而设计的库函数之外,不保证原子读 - 修改 - 写,例如在递增或递减的情况下.
| 归档时间: |
|
| 查看次数: |
13124 次 |
| 最近记录: |