我可以使用C#创建优先级同步锁吗?

时间:2013-05-27 19:42:05

标签: c# .net synchronization locking ipc

我目前正在使用Mutex在进程之间建立对文件的同步访问:

//Process 1
//High frequency "writes"
try
{
    mutex.WaitOne(System.Threading.Timeout.Infinite);

    try
    {
        //Do write operation

    }
    finally
    {
        mutex.ReleaseMutex();
    }
}
catch(AbandonedMutexException)
{
    //Log error
}

然后有时我可能需要检查写入文件的内容:

//Process 2
//Low frequency "reads"
try
{
    mutex.WaitOne(System.Threading.Timeout.Infinite);

    try
    {
        //Do read operation

    }
    finally
    {
        mutex.ReleaseMutex();
    }
}
catch(AbandonedMutexException)
{
    //Log error
}

但是这种技术会发生的情况是,正在进行低频“读取”的Process 2似乎挂断并且从未接收过对资源的访问权限,或者这可能需要很长时间才能完成。

在我的情况下是否有更好的锁定使用?

PS。它必须兼容才能在进程之间使用。

2 个答案:

答案 0 :(得分:1)

我想我通过介绍一个事件来修复它:

EventWaitHandle event = new EventWaitHandle(true, 
     EventResetMode.ManualReset, 
     strEventGlobalName,     //Must be the same for each process
     out dummy, 
     eventSecurity);         //To allow access between processes

所以作者将这样看:

//Process 1
//High frequency "writes"

//Wait to allow writing
if (event.WaitOne(System.Threading.Timeout.Infinite))
{
    try
    {
        mutex.WaitOne(System.Threading.Timeout.Infinite);

        try
        {
            //Do write operation

        }
        finally
        {
            mutex.ReleaseMutex();
        }
    }
    catch(AbandonedMutexException)
    {
        //Log error
    }
}

和读者一样:

//Process 2
//Low frequency "reads"

try
{
    //Reset event to halt writing
    if (!event.Reset())
        throw new Exception("Did not reset event");

    try
    {
        mutex.WaitOne(System.Threading.Timeout.Infinite);

        try
        {
            //Do read operation

        }
        finally
        {
            mutex.ReleaseMutex();
        }
    }
    catch(AbandonedMutexException)
    {
        //Log error
    }
}
finally
{
    //Set event to allow back writing
    if(!event.Set())
        throw new Exception("Did not set event");
}

答案 1 :(得分:0)

您是否正在使用这样的命名Mutex?:

bool created = false;       
string mutexHandle = "SOME_UNIQUE_ENOUGH_STRING_slkuhfwer7487rctcwf6gt86efcwwgsa";
var myFileLock = new Mutex(true, mutexHandle, out created);

因为只有一个命名的Mutex可用于在系统级别的进程之间同步任务。

如果是这样,你在做正确的事情(技术上)。

但是如果你在一端进行高频操作;你应该在作者之前Thread.Sleep(1);之前提供mutex.WaitOne(System.Threading.Timeout.Infinite);之间的差距(例如);或者您可能应该使用其他方法,如内存映射文件,或写入新标记文件(通过在名称中提供时间戳并删除读取文件)或使用为您提供文件版本控制的工具。