这个Pointer算术真的是线程安全吗?

时间:2013-09-18 13:13:35

标签: c# multithreading

我已经看到以下建议在网络上进行指针运算:

IntPtr ptr = new IntPtr(oldptr.ToInt64() + 2);

这真的是线程安全吗?我想不是因为ToInt64和加法不是原子的。这是.NET4中新IntPtr.Add()函数的原因吗?

http://msdn.microsoft.com/en-us/library/system.intptr.add.aspx

修改

根据您的好评,阅读了线程安全性后,我想我可以澄清一下我的问题。我担心的是垃圾收集器可能会在我使用ToInt64()得到它的值时移动指针并创建新的IntPtr。所以,我的问题是:

ToInt64()ToInt32()将返回“64位/ 32位有符号整数,等于此实例的值。” (MSDN)。我猜这个值是数据的真实地址(指针)。我想如果GC碰巧移动数据,这个值将不会相应更新。因此,基于此值创建新的IntPtr可能指向错误的位置。我想你必须使用固定/固定指针来防止这种情况。

2 个答案:

答案 0 :(得分:4)

通过线程安全我想你关注与多个线程在同一个变量上执行读 - 修改 - 写周期相关的竞争条件。这不是你在代码中的问题。使用该代码预测的线程问题并不明显。

也许您打算使用的例子是:

IntPtr ptr = ...;
...
ptr = (IntPtr) (ptr.ToInt64() + 2);

现在,该代码不是线程安全的。如果多个线程同时执行read-modify-write,则会有经典的数据争用。

但是,新的IntPtr.Add方法也不是线程安全的。新的加法运营商也不是。我的意思是说ptr += 2不是线程安全的,例如。

您需要一个锁或Interlocked类来实现线程安全递增。

答案 1 :(得分:1)

  

这是.NET4中新的IntPtr.Add()函数的原因吗?

只有猜测,但更可能的原因是:

  

不支持运算符重载或自定义运算符的语言可以使用此方法向指针值添加偏移量。“