.net 4.0 如何对.Net中的内存映射文件使用联锁操作
是否有任何方法可以使用.net 4.0 如何对.Net中的内存映射文件使用联锁操作,.net-4.0,memory-mapped-files,interlocked,.net 4.0,Memory Mapped Files,Interlocked,是否有任何方法可以使用Interlocked.CompareExchange()和联锁。增量()针对存储在内存映射文件中的值的方法 我想实现一个多线程服务,将其数据存储在内存映射文件中,但由于它是多线程的,我需要防止冲突写入,因此我想知道联锁操作,而不是使用显式锁 我知道使用本机代码是可能的,但是可以在.NET 4.0上的托管代码中完成吗?好的,这就是您要做的!我们必须解决这个问题,我想我们可以还给stackoverflow一些 class Program { internal sta
Interlocked.CompareExchange()代码>和联锁。增量()代码>针对存储在内存映射文件中的值的方法
我想实现一个多线程服务,将其数据存储在内存映射文件中,但由于它是多线程的,我需要防止冲突写入,因此我想知道联锁操作,而不是使用显式锁
我知道使用本机代码是可能的,但是可以在.NET 4.0上的托管代码中完成吗?好的,这就是您要做的!我们必须解决这个问题,我想我们可以还给stackoverflow一些
class Program
{
internal static class Win32Stuff
{
[DllImport("kernel32.dll", SetLastError = true)]
unsafe public static extern int InterlockedIncrement(int* lpAddend);
}
private static MemoryMappedFile _mmf;
private static MemoryMappedViewStream _mmvs;
unsafe static void Main(string[] args)
{
const int INT_OFFSET = 8;
_mmf = MemoryMappedFile.CreateOrOpen("SomeName", 1024);
// start at offset 8 (just for example)
_mmvs = _mmf.CreateViewStream(INT_OFFSET, 4);
// Gets the pointer to the MMF - we dont have to worry about it moving because its in shared memory
var ptr = _mmvs.SafeMemoryMappedViewHandle.DangerousGetHandle();
// Its important to add the increment, because even though the view says it starts at an offset of 8, we found its actually the entire memory mapped file
var result = Win32Stuff.InterlockedIncrement((int*)(ptr + INT_OFFSET));
}
}
这是可行的,并且可以跨多个流程工作!永远享受好的挑战 ,实际上您可以使用Interlocked.Increment静态方法,正如前面所说的,您只需小心指针转换和运算符优先级,加上括号的使用,事实上
将内存指针(加上所需的偏移量)强制转换为指向int变量的指针,然后将该指针用作变量。然后您必须将其用作变量引用
在下面,您将找到使用.net库而不是外部静态导入的相应代码段
损益表
也在寻找这个。你找到解决办法了吗?在下面贴了一个答案。请接受!!!:)谢谢。你知道x64的正确解决方案是什么吗?由于intterlocked函数不是从64位版本的kernel32导出的。dllI没有为x64提供解决方案,但几个月前,我们在使用64位操作系统瞄准任何CPU时,确实遇到过这种情况。欢迎任何意见!为什么不使用.Net Interlocked.Increment?因为我们处理的是指针,而不是.net Int32——所以我们必须使用ptr+偏移量来增加内存映射文件中的值。
class Program
{
private static MemoryMappedFile _mmf;
private static MemoryMappedViewStream _mmvs;
static void Main(string[] args)
{
const int INT_OFFSET = 8;
_mmf = MemoryMappedFile.CreateOrOpen("SomeName", 1024);
_mmvs = _mmf.CreateViewStream(INT_OFFSET, 4);
unsafe
{
IntPtr ptr = _mmvs.SafeMemoryMappedViewHandle.DangerousGetHandle();
Interlocked.Increment(ref (*((int*)(ptr + INT_OFFSET)))
}
}
}