c# lock 和 Mutex 的区别和性能 lock和Mutex哪个好

lock是纯托管同步原语,仅限同一进程内线程间使用;Mutex是内核对象,支持跨进程同步但每次调用引发用户态/内核态切换,性能相差一个数量级。

c# lock 和 mutex 的区别和性能 lock和mutex哪个好

lock 和 Mutex 的本质区别在哪?

lock 是 C# 关键字,底层直接调用 Monitor.EnterMonitor.Exit,纯托管、无系统调用;Mutex 是 Windows 内核对象(.NET 封装),每次 WaitOne / ReleaseMutex 都会触发用户态 → 内核态切换。这意味着:
lock 只能在**同一进程内**的线程间同步
Mutex 可跨进程、跨 AppDomain,甚至能被其他语言(如 C++)创建的进程识别

性能差距有多大?实际测出来才信

在单进程多线程场景下,lockMutex 快一个数量级。实测(0xFFFFF ≈ 1048575 次临界区进入):
lock:约 1335 ms
Mutex:通常在 10000+ ms 量级(取决于系统负载)
原因不是“Mutex 写得差”,而是每次等待都得进内核——哪怕锁立刻可用,也要走一遍上下文切换开销。

private void TestWithLock(int times)
{
    for (int i = 0; i < times; i++)
    {
        lock (_lockObj) { Acc(i); }
    }
}

private void TestWithMutex(int times) { for (int i = 0; i < times; i++) { _mutex.WaitOne(); // 这里就已进内核 try { Acc(i); } finally { _mutex.ReleaseMutex(); } } }

什么时候非用 Mutex 不可?

只有当你要解决**跨进程竞争**时才需要 Mutex,例如:
• 多个独立 EXE 程序共用同一个本地数据库文件(需确保写入互斥)
• Windows 服务 + 桌面客户端共享配置缓存文件
• 单实例应用(通过命名 Mutex 检测是否已有进程运行)
其他所有情况——包括 ASP.NET 请求处理、后台任务队列、内存缓存更新——都该用 lockMonitor

Kive

Kive

一站式AI图像生成和管理平台

下载

  • 别用 lock(this)lock(typeof(MyClass)):容易引发外部死锁
  • 别把 intstring 当锁对象:string 有字符串驻留,int 会装箱成不同对象,导致锁失效
  • Mutex 创建时若传入名称(如 new Mutex(false, "MyApp.GlobalLock")),它就变成全局内核对象,必须注意权限和释放——忘了 ReleaseMutex 会导致其他进程永久阻塞

Monitor 能不能替代 Mutex?

不能。Monitorlock 一样,只作用于当前进程内的线程;它比 lock 多出 TryEnter(可设超时防死锁)、Wait/Pulse(线程协作),但依然**不跨进程**。如果你只是想避免 lock 无法超时的问题,用 Monitor.TryEnter(obj, timeout) 即可,无需升格到 Mutex

真正该警惕的,不是“选错锁”,而是“根本不需要锁”——比如只读静态数据、每个线程独享的局部变量、或已被 ConcurrentDictionary 等线程安全集合封装的操作。加锁是手段,不是目的。

https://www.php.cn/faq/2016028.html

发表回复

Your email address will not be published. Required fields are marked *