【发布时间】:2019-05-05 04:22:05
【问题描述】:
值类型的赋值在.Net中被认为是原子的吗?
例如,考虑以下程序:
struct Vector3
{
public float X { get; private set; }
public float Y { get; private set; }
public float Z { get; private set; }
public Vector3(float x, float y, float z)
{
this.X = x;
this.Y = y;
this.Z = z;
}
public Vector3 Clone()
{
return new Vector3(X, Y, Z);
}
public override String ToString()
{
return "(" + X + "," + Y + "," + Z + ")";
}
}
class Program
{
private static Vector3 pos = new Vector3(0,0,0);
private static void ReaderThread()
{
for (int i = 0; i < int.MaxValue; i++)
{
Vector3 v = pos;
Console.WriteLine(v.ToString());
Thread.Sleep(200);
}
}
private static void WriterThread()
{
for (int i = 1; i < int.MaxValue; i++)
{
pos = new Vector3(i, i, i);
Thread.Sleep(200);
}
}
static void Main(string[] args)
{
Thread w = new Thread(WriterThread);
Thread r = new Thread(ReaderThread);
w.Start();
r.Start();
}
}
这样的程序会遭受高级数据竞争吗?甚至是数据竞赛?
我在这里想知道的是:v 是否有可能包含:
- 可能的数据竞争导致的垃圾值
- 指代分配前的位置和分配后的位置的混合组件 X、Y 或 Z。例如,如果 pos = (1,1,1) 然后 pos 被赋予 (2,2,2) 的新值,可以 v = (1,2,2) 吗?
【问题讨论】:
-
正如我所写的,我很确定它甚至没有编译,
bw没有定义。也就是说,值类型复制,所以我不确定它会做什么(对你),即使它的 not 线程安全。 -
这或多或少是伪代码,我可以将其更改为完整代码,但它实际上是否为问题添加了任何内容?
-
并非所有的值类型赋值都是原子的。看看接受的答案:stackoverflow.com/questions/2433772/…。
-
我只是想弄清楚你在这里问的是什么。
v的分配不会在pos重新分配时受到影响,线程或无线程。该操作将花费复制操作所需的时间(我怀疑这是任何一种原子) -
“但它是否真的给问题增加了任何东西”。 是的。有两种方式:1)当读者阅读你的代码时,如果有些东西很奇怪,而且你的代码是可编译的,那么它真的很奇怪。在这种情况下,您的代码无法编译,因此它可能只是随机的绒毛。 2)如果你的代码编译,我可以复制它,编译它,调试它等等。
标签: c# thread-safety atomic value-type tearing