今天早些时候,我正在debugging的东西有点像这样:
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
作为其互斥体。 这个操作不是primefaces操作的,其他进程只是在另一个进程正在使用的时候没有通过关键部分(如果你能相信的话,他们打算能够在锁释放后继续)等等。显然它需要被修复。
如何正确获取锁以同步多个进程间的文件系统访问? 这些进程是同一进程的多个实例,所以他们可以共享一些协议,而不是专门locking目录(也就是说,他们可以很容易地使用相当于某些类的所有实例的东西,像private final static Object lock = new Object();
同步对静态方法的访问)
你应该使用互斥体 。
同步原语也可用于进程间同步 。
互斥对于一个进程来说是本地的 ,或者是被命名的 。 为了支持进程间的同步,你需要使用一个有名的互斥体 。
在整个操作系统中,命名系统互斥是可见的,并且可以用来同步进程的活动。
下面是一个示例程序,演示使用共享互斥体进行进程间同步。
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); } } } }
示例程序输出:
紫色的线条表示在两个进程之间传输共享互斥量的控制点。
要同步对单个文件的访问,您应该使用基于受保护文件的规范化路径的互斥体名称。
以下是如何创建标准化路径 :
public static string NormalizePath(string path) { return Path.GetFullPath(new Uri(path).LocalPath) .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) .ToUpperInvariant(); }