2

我已经看到了以下关于在整个网络上进行指针运算的建议:

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

那真的是线程安全的吗?我猜不是因为ToInt64and 加法不是原子的。这就是 .NET4 中新IntPtr.Add()功能的原因吗?

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

编辑

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

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

4

2 回答 2

4

通过线程安全,我假设您关心与对同一变量执行读取-修改-写入循环的多个线程相关的竞争条件。这不是您在问题代码中的内容。您对该代码的预期线程问题并不明显。

也许您打算使用的示例是这样的:

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

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

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

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

于 2013-09-18T13:26:18.320 回答
1

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

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

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

于 2013-09-18T13:24:01.143 回答