Linux 下的互斥行为

Rüd*_*ger 7 .net c# .net-6.0

我正在尝试通过多进程控制台应用程序控制访问,以便一次只有一个进程可以运行代码的特定部分。

\n

实际上,我想为此使用互斥体,但互斥体类似乎不适用于 Linux。

\n

我的代码:

\n
using var mutex = new Mutex(false, @"Global\\TestMutex");\nif (mutex.WaitOne(0, false)) {\n    Console.WriteLine("Mutex erhalten");\n} else {\n    Console.WriteLine("Mutex nicht erhalten");\n}\nConsole.WriteLine("Beliebige Taste dr\xc3\xbccken zum beenden.");\nConsole.ReadKey();\n
Run Code Online (Sandbox Code Playgroud)\n

在 Windows 上工作:

\n

Windows 上的结果

\n

不适用于 Linux (Ubuntu 22.04/NET6):

\n

Linux 上的结果

\n

我错过了什么吗?

\n
\n

我当前的解决方法是有一个“Lockfile”,但我不想维护额外的实用程序类。

\n

实用类:

\n
public class LockfileMutex : IDisposable {\n    private readonly string _fileName;\n\n    private FileStream? _stream;\n\n    public LockfileMutex(string name) {\n        var assemblyDir = Path.GetDirectoryName(typeof(LockfileMutex).Assembly.Location) ?? throw new FileNotFoundException("cannot determine assembly location");\n        var file = Path.GetFullPath(Path.Combine(assemblyDir, name));\n        _fileName = file;\n    }\n\n    public bool Acquire() {\n        try {\n            _stream = new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);\n            return true;\n        } catch (IOException ex) when (ex.Message.Contains(_fileName)) {\n            return false;\n        }\n    }\n\n    public void Dispose() {\n        if (_stream != null) {\n            _stream.Dispose();\n\n            try {\n                File.Delete(_fileName);\n            } catch {\n                // ignored\n            }\n        }\n\n        GC.SuppressFinalize(this);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

用法:

\n
using (var mutex = new LockfileMutex("MyMutex")) {\n    if (mutex.Acquire()) {\n        Console.WriteLine("acquired");\n    } else {\n        Console.WriteLine("not acquired");\n    }\n    Console.WriteLine("press any key to end");\n    Console.ReadKey();\n}\n
Run Code Online (Sandbox Code Playgroud)\n