Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以原子方式将整数写入虚拟内存?_C#_Multithreading - Fatal编程技术网

C# 以原子方式将整数写入虚拟内存?

C# 以原子方式将整数写入虚拟内存?,c#,multithreading,C#,Multithreading,我有一个指向进程虚拟内存中某个位置的指针(IntPtr),我需要能够将一个32位整数原子地写入该位置,因为可能有几个本机线程从该位置读/写整数。目前我正在使用Marshal.WriteInt32来执行此操作,但我不确定此函数是否以原子方式写入内存 到目前为止,我还并没有在测试中遇到比赛情况,但我想确定一下。所有的封送.WriteInt*函数都是以原子方式写入内存的吗?如果没有,我该怎么做呢?看看它的实现,似乎对齐写入是原子的,而非对齐写入不是原子的 如果没有,我怎么做 与往常一样,任何非原子操作

我有一个指向进程虚拟内存中某个位置的指针(
IntPtr
),我需要能够将一个32位整数原子地写入该位置,因为可能有几个本机线程从该位置读/写整数。目前我正在使用
Marshal.WriteInt32
来执行此操作,但我不确定此函数是否以原子方式写入内存


到目前为止,我还并没有在测试中遇到比赛情况,但我想确定一下。所有的
封送.WriteInt*
函数都是以原子方式写入内存的吗?如果没有,我该怎么做呢?

看看它的实现,似乎对齐写入是原子的,而非对齐写入不是原子的

如果没有,我怎么做


与往常一样,任何非原子操作都可以通过同步访问来实现原子化。使用某种同步。进程内同步可以通过lock语句轻松完成。对于进程间同步,您可以使用互斥(假设您控制两个进程)

WriteInt32
将始终是原子的,只要内存正确对齐。在直接写入其他人的内存时,没有可以使用的同步原语,因此这实际上是您唯一的赌注

然而,这只意味着你不会被撕碎的写或读——这并不能保证其他人会看到你所写的价值。如果您需要在进程之间共享数据,只需协同工作即可。在最好的情况下,直接向另一个进程写入内存是很棘手的,而且在大多数情况下是非常危险的


处理同步访问的最简单方法是使用互斥锁——只要每个应用程序都遵循正确的协议,您就安全了,不管写操作是原子的还是非原子的。但实际上,只需在进程之间使用其他一些通信方法—直接内存操作从未得到支持。更不用说它给你的进程提供了太多的特权以使你感到舒适:)

我尝试过:
不安全的{Interlocked.Exchange(ref*((int*)ptr),42);}
其中
ptr
是指向内存位置的
IntPtr
指针,它似乎工作正常。你觉得这个解决方案怎么样?或者我应该简单地使用
*((int*)ptr)=42

来处理CLI方面的事情,但就我所知,一旦你离开运行时,所有的赌注似乎都没有了。如果我是你,我会尝试@HenkHolterman,如果我们能够控制这些线程,我们也可以在那里提供同步,对吧。为什么不简单地使用内存围栏?@SergeyA我不会用“内存围栏”和“简单”:D无锁线程安全编程非常棘手,很少需要。只有当你有确凿的证据表明这意味着显著的性能提升时,这才是值得的。我怀疑如果是这样的话,OP只会使用
不安全的
代码,而不是使用
封送
。别误会——我对C一无所知:),但使用内存围栏在概念上没有什么困难(当然,thorugh OS提供了原语)还有很多重要的案例要求你使用无锁结构。@Luaan:我不明白你对Alex的回答的观点,我想理解它。你能详细说明一下吗?编辑:答案现在被删除了,但是你说了一些关于线程安全方法具有不受保护的内存写入的内容。@displayName文档说静态成员是线程安全的。这并不意味着它神奇地为您解决了所有并发问题-它只是意味着您不必确保所有
Marshal
调用都来自同一个线程。这与使用例如
File.writealText
的方法类似-该方法本身是线程安全的,但这并不意味着两个线程(或应用程序)试图同时写入同一文件就可以工作。无论何时使用共享资源,都必须确保以某种方式同步使用该共享资源的所有代码。