有没有办法在内存映射文件中使用 Interlocked.CompareExchange();
和 Interlocked.Increment();
方法?
我想实现一个多线程服务,将其数据存储在内存映射文件中,但由于它是多线程的,我需要防止冲突写入,因此我想使用Interlocked操作而不是使用显式锁。
我知道这在本机代码中是可能的,但在.NET 4.0上的托管代码中是否可以实现?
有没有办法在内存映射文件中使用 Interlocked.CompareExchange();
和 Interlocked.Increment();
方法?
我想实现一个多线程服务,将其数据存储在内存映射文件中,但由于它是多线程的,我需要防止冲突写入,因此我想使用Interlocked操作而不是使用显式锁。
我知道这在本机代码中是可能的,但在.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));
}
}
这是有效的,而且可以在多个进程中工作!总是喜欢一个好的挑战!
你将把一个内存指针(加上所需的偏移量)转换为int变量的指针,然后将该指针用作变量。然后你将必须将其用作变量引用。
下面是您的对应片段,使用.net库而不是外部静态导入。
P&L
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)))
}
}
}