我有一个指针(IntPtr
)到进程虚拟内存中的某个位置,我需要能够原子地将32位整数写入此位置,因为可以有几个本机线程读取/从/到此位置写入整数。目前我使用Marshal.WriteInt32
来执行此操作,但我不确定此函数是否以原子方式写入内存。
到目前为止,我还没有在测试期间遇到竞争状况,但我想肯定地知道。所有Marshal.WriteInt*
函数都是以原子方式写入内存吗?如果没有,我该怎么办?
答案 0 :(得分:2)
看看Marshal.WriteInt32的实现,似乎对齐写入是原子的,非对齐写入不是原子的。
如果没有,我该怎么做?
像往常一样,任何非原子操作都可以通过同步访问来实现原子操作。使用某种同步。使用锁定语句可以轻松完成内部进程同步。对于Inter进程同步,您可以使用Mutex。(假设您可以控制两个进程)
答案 1 :(得分:2)
WriteInt32
将始终是原子的。在直接写入别人的记忆时,你可以使用同步原语,所以这真的是你唯一的选择。
然而,它只意味着你不会被撕裂的写入或读取 - 它不会保证任何人都会看到你写的价值。如果您需要在流程之间共享数据,那么只需将其合并即可。直接写入另一个进程内存在最好的时候是棘手的,而且大部分时间都是彻头彻尾的危险。
处理同步访问的最简单方法是使用互斥锁 - 只要每个应用程序都遵循正确的协议,无论写入是否为原子,都是安全的。但实际上,只需在进程之间使用其他一些通信方法 - 从未支持直接内存操作。更不用说它为你的流程提供了太多的舒适权限:)
答案 2 :(得分:1)
我试过这个:IntPtr
其中*((int*)ptr) = 42
是指向内存位置的{{1}}指针,它似乎工作正常。您对此解决方案有何看法?或者我应该只使用{{1}}?