如何在C#中使进程(而非线程)同步文件系统访问 [英] How to have processes (not threads) in C# synchronize file system access

查看:108
本文介绍了如何在C#中使进程(而非线程)同步文件系统访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天早些时候,我正在调试类似以下的内容:

Earlier today I was debugging something that went a bit like this:

class Foo {

    void AccessCriticalSection() {
        try {
            if (IO.File.Exists("\\path\to\lock.txt")
                throw new Exception();
            System.IO.File.Create("\\path\to\lock.txt");
            criticalSection();          
        } catch (Exception ex) {
            // ignored
        } 
    }

    void CriticalSection() {
        // banana banana banana
        System.IO.File.Delete("\\path\to\lock.txt");
    }

}

我们什至不了解这有多可怕……但是,它实际上是在尝试使用名为lock.txt的文件作为其互斥量.该操作不是原子操作,如果其他进程正在使用它,其他进程只是无法通过关键部分(如果可以相信,它们应该能够在释放锁之后继续运行),等等.它需要修复.

Let's not even get into how terrible this is… but it's essentially trying to use a file called lock.txt as its mutex. The operation isn't atomic, other processes are just not getting through the critical section if another process is using it (they're intended to be able to continue after the lock is released if you can believe it), etc. etc. Obviously it needs to be fixed.

如何正确获取锁以跨多个进程同步对文件系统的访问?这些进程是同一进程的多个实例,因此它们可以共享某种协议,而不是专门锁定目录(即,它们可以轻松地使用与某些类的所有实例等效的东西锁定在诸如private final static Object lock = new Object();之类的东西上)来同步对静态方法)

How do I properly obtain a lock to synchronize access to the filesystem across multiple processes? The processes are multiple instances of the same process, so they can share some protocol rather than specifically locking the directory (i.e., they can easily use what is the equivalent to all instances of some class locking on something like private final static Object lock = new Object(); to synchronize access to static methods)

推荐答案

您应使用

一个同步原语,也可以用于进程间同步.

Mutexes在进程中是 local 或在名称中是 .为了支持进程间同步,您需要使用名为 mutex 的互斥锁.

Mutexes are either local to a process or named. To support interprocess synchronization you'll need to use a named mutex.

命名的系统互斥锁在整个操作系统中都是可见的,可用于同步进程的活动.

Named system mutexes are visible throughout the operating system, and can be used to synchronize the activities of processes.


这是一个示例程序,演示了使用共享互斥锁进行进程间同步.


Here's a sample program that demonstrate interprocess synchronization using a shared mutex.

class Program
{
    static void Main(string[] args)
    {
        const string SHARED_MUTEX_NAME = "something";
        int pid = Process.GetCurrentProcess().Id;

        using (Mutex mtx = new Mutex(false, SHARED_MUTEX_NAME))
        {
            while (true)
            {
                Console.WriteLine("Press any key to let process {0} acquire the shared mutex.", pid);
                Console.ReadKey();

                while (!mtx.WaitOne(1000))
                {
                    Console.WriteLine("Process {0} is waiting for the shared mutex...", pid);
                }

                Console.WriteLine("Process {0} has acquired the shared mutex. Press any key to release it.", pid);
                Console.ReadKey();

                mtx.ReleaseMutex();
                Console.WriteLine("Process {0} released the shared mutex.", pid);
            }
        }            
    }
}

示例程序输出:

紫色线显示了在两个进程之间转移共享互斥锁的控制点.

The purple lines show points where control of the shared mutex is transferred between the two processes.

要同步对单个文件的访问,您应该使用基于受保护文件的规范化路径的互斥体名称.

To synchronize access to individual files you should use a mutex name that is based on a normalized path of the protected file.

这是创建标准化路径的方法:

public static string NormalizePath(string path)
{
    return Path.GetFullPath(new Uri(path).LocalPath)
               .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
               .ToUpperInvariant();
}

这篇关于如何在C#中使进程(而非线程)同步文件系统访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆