Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Mutex Class ใน C#: การซิงโครไนซ์ข้าม Process

ภาพรวม

Mutex (Mutual Exclusion) เป็น Synchronization Primitive ที่ทำงานข้าม Process ได้ (Cross-process) ใช้สำหรับป้องกันการเข้าถึงทรัพยากรร่วมกันระหว่าง Process หลายตัว

การสร้าง Mutex


using System;
using System.Threading;

// 1. Unnamed Mutex (Local to Process)
Mutex localMutex = new Mutex();

// 2. Named Mutex (Cross-Process)
Mutex namedMutex = new Mutex(false, "Global\\MyAppMutex");

// 3. Named Mutex with Initial Ownership
Mutex ownedMutex = new Mutex(true, "MyAppMutex", out bool createdNew);

พารามิเตอร์ Constructor

Parameterคำอธิบาย
bool initiallyOwnedtrue = เธรดสร้างเป็น Owner ทันที, false = ไม่ได้เป็น Owner
string nameชื่อ Mutex (ใช้ Global\\ สำหรับ Cross-session, Local\\ สำหรับ Session เดียว)
out bool createdNewคืนค่า true ถ้าสร้างใหม่, false ถ้า Mutex ชื่อนี้มีอยู่แล้ว

ตัวอย่าง: Single Instance Application


using System;
using System.Threading;

class Program {
    static Mutex _mutex;

    static void Main() {
        bool createdNew;
        _mutex = new Mutex(true, "Global\\MyUniqueAppId-{GUID}", out createdNew);

        if (!createdNew) {
            Console.WriteLine("Another instance is already running.");
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
            return;
        }

        try {
            Console.WriteLine("Application started. Press Enter to exit.");
            Console.ReadLine();
        }
        finally {
            _mutex.ReleaseMutex();
        }
    }
}

ตัวอย่าง: Interprocess Synchronization


// Process A (Writer)
using (var mutex = new Mutex(false, "Global\\SharedDataMutex")) {
    mutex.WaitOne();
    try {
        // Write to shared memory / file
        File.WriteAllText("shared.txt", DateTime.Now.ToString());
        Console.WriteLine("Data written.");
    }
    finally {
        mutex.ReleaseMutex();
    }
}

// Process B (Reader)
using (var mutex = new Mutex(false, "Global\\SharedDataMutex")) {
    mutex.WaitOne();
    try {
        string data = File.ReadAllText("shared.txt");
        Console.WriteLine($"Data read: {data}");
    }
    finally {
        mutex.ReleaseMutex();
    }
}

Mutex vs Lock

FeatureMutexlock (Monitor)
Cross-ProcessYes (Named)No
ReentrantNo (Default)Yes
PerformanceSlower (Kernel Object)Faster (User Mode)
TimeoutWaitOne(TimeSpan)Monitor.TryEnter(TimeSpan)
Abandoned MutexThrow AbandonedMutexExceptionN/A

Best Practices

  • ใช้ชื่อ Unique (GUID) ป้องกันชื่อชน
  • ใช้ Global\\ Prefix สำหรับ System-wide, Local\\ สำหรับ Session-wide
  • ใช้ using Statement หรือ try/finally เพื่อ Release แน่ใจ
  • จับ AbandonedMutexException เมื่อ Owner Terminate โดยไม่ Release
  • หลีกเลี่ยง Mutex สำหรับ In-process Synchronization (ใช้ lock/ReaderWriterLockSlim แทน)