锁和互斥体有什么区别?

发布于 2024-09-24 04:42:01 字数 30 浏览 2 评论 0原文

锁和互斥体有什么区别?为什么它们不能互换使用?

What is the difference between lock and Mutex? Why can't they be used interchangeably?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

怼怹恏 2024-10-01 04:42:01

锁定 特定于 AppDomain,而 与操作系统互斥,允许您执行进程间锁定和同步(IPC)。

A lock is specific to the AppDomain, while Mutex to the Operating System allowing you to perform inter-process locking and synchronization (IPC).

攀登最高峰 2024-10-01 04:42:01

lock 是编译器关键字,而不是实际的类或对象。它是 Monitor 类功能的包装器,旨在使 Monitor 在常见情况下更易于使用。

正如 Darin 所说,Monitor(和 lock 关键字)仅限于 AppDomain。主要是因为需要引用内存地址(以实例化对象的形式)来管理“锁”并维护Monitor的身份

Mutex,另一方面,它是围绕操作系统构造的 .Net 包装器,可用于系统范围的同步,使用字符串 data (而不是指向数据的指针)作为其标识符。引用两个完全不同的内存地址中的两个字符串但具有相同数据的两个互斥体实际上将利用相同的操作系统互斥体。

lock is a compiler keyword, not an actual class or object. It's a wrapper around the functionality of the Monitor class and is designed to make the Monitor easier to work with for the common case.

The Monitor (and the lock keyword) are, as Darin said, restricted to the AppDomain. Primarily because a reference to a memory address (in the form of an instantiated object) is required to manage the "lock" and maintain the identity of the Monitor

The Mutex, on the other hand, is a .Net wrapper around an operating system construct, and can be used for system-wide synchronization, using string data (instead of a pointer to data) as its identifier. Two mutexes that reference two strings in two completely different memory addresses, but having the same data, will actually utilize the same operating-system mutex.

水染的天色ゝ 2024-10-01 04:42:01

互斥体可以是本地进程或系统范围MSDN

互斥体有两种类型:本地互斥体(未命名)和命名系统互斥体。本地互斥体仅存在于您的进程中。

此外,在具有终端服务的系统上使用系统范围的互斥锁时,应特别小心(在同一页上也有详细说明)。

Mutexlock 之间的区别之一是 Mutex 使用 内核级构造,因此同步始终至少需要一次用户空间-内核空间转换。

lock - 这实际上是 Monitor,另一方面,试图避免分配内核资源并转换到内核代码(因此更精简且更快 - 如果必须找到类似于的 WinAPI 构造) ,它将是 CriticalSection)。

另一个区别是其他人指出的:命名 互斥体 可以跨进程使用。

除非有特殊需求或需要跨进程同步,否则最好坚持使用lock(又名Monitor)˛

还有其他几个“细微”差异,例如如何放弃 3.5 中的 ReaderWriterLock

ReaderWriterLockSlimSemaphore 和新的 SemaphoreSlim 也可以这样说在.NET 4.0等中
确实,后面的 xxSlim 类不能用作系统范围的同步原语,但它们从来就不是这样的——它们“只是”意味着更快、更资源友好。

A Mutex can be either local to a process or system-wide. MSDN:

Mutexes are of two types: local mutexes, which are unnamed, and named system mutexes. A local mutex exists only within your process.

Furthermore, one should take special care - detailed on the same page as well - when using a system-wide mutex on a system with Terminal Services.

One of the differences between Mutex and lock is that Mutex utilizes a kernel-level construct, so synchronization will always require at least a user space-kernel space transition.

lock - that is really a shortcut to the Monitor class, on the other hand tries to avoid allocating kernel resources and transitioning to kernel code (and is thus leaner & faster - if one has to find a WinAPI construct that it resembles, it would be CriticalSection).

The other difference is what others point out: a named Mutex can be used across processes.

Unless one has special needs or requires synchronization across processes, it is just better to stick to lock (aka Monitor

There are several other "minor" differences, like how abandonment is handled, etc.

The same can be said about ReaderWriterLock and ReaderWriterLockSlim in 3.5, Semaphore and the new SemaphoreSlim in .NET 4.0 etc.
It is true that the latter xxSlim classes cannot be used as a system-wide sync primitives, but they were never meant to - they were "only" meant to be faster and more resource friendly.

她说她爱他 2024-10-01 04:42:01

我使用互斥体来检查是否已经有在同一台计算机上运行的应用程序的副本。

bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);

if (!firstInstance)
{
    //another copy of this application running 
}
else
{
    //run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);

I use a Mutex to check see if I already have a copy of the application running on the same machine.

bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);

if (!firstInstance)
{
    //another copy of this application running 
}
else
{
    //run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);
我乃一代侩神 2024-10-01 04:42:01

已经说了很多了,但为了简单起见,这是我的看法。

锁定 ->使用简单,监视器上的包装器,跨 AppDomain 中的线程锁定。

未命名互斥量 ->与lock类似,只是锁定范围更大,并且它跨进程中的AppDomain。

命名互斥量 ->锁定范围甚至比未命名的互斥量还要大,并且它跨操作系统中的进程。

现在选项已经有了,您需要选择最适合您情况的一种。

A lot has been said already, but to make it simple, here's my take.

lock -> Simple to use, wrapper on monitor, locks across threads in an AppDomain.

unnamed mutex -> similar to lock except locking scope is more and it's across AppDomain in a process.

Named mutex -> locking scope is even more than unnamed mutex and it's across process in an operating system.

So now options are there, you need to choose the one fits best in your case.

很快妥协 2024-10-01 04:42:01

互斥体是一种跨进程,并且会有一个不运行多个应用程序实例的经典示例。

第二个例子是说你有一个文件并且你不希望不同的进程访问同一个文件,你可以实现一个互斥体,但请记住一件事互斥体是操作系统范围的,不能在两个远程进程之间使用。

锁定是保护代码部分的最简单方法,并且它是特定于应用程序域的,如果您想要更多受控同步,可以用监视器替换锁定。

Mutex is a cross process and there will be a classic example of not running more than one instance of an application.

2nd example is say you are having a file and you don't want different process to access the same file , you can implement a Mutex but remember one thing Mutex is a operating system wide and cannot used between two remote process.

Lock is a simplest way to protect section of your code and it is appdomain specific , you can replace lock with Moniters if you want more controlled synchronization.

柠檬色的秋千 2024-10-01 04:42:01

答案中没有提到的一些细微差别:

  1. 在使用锁的情况下,您可以确保当锁块内发生异常时锁将被释放
    这是因为该锁在后台使用监视器并实现了

  2. 对于锁,您通常使用私有对象来锁定(并且应该使用)。
    这样做的原因有很多。 (更多信息:查看此答案官方文档)。

因此,在锁定的情况下,您无法(意外获得)从外部访问锁定的对象并造成一些损坏。
但对于互斥体,您可以,因为通常有一个标记为公共的互斥体并可以在任何地方使用。

Few more minor differences which were not mentioned in the answers:

  1. In the case of using locks, you can be sure that the lock will be released when an exception happens inside the lock's block.
    That's because the lock uses monitors under the hood and is implemented this way:

     object __lockObj = x;
     bool __lockWasTaken = false;
     try
     {
         System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
         // Your code...
     }
     finally
     {
         if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
     }
    

    Thus, in any case, the lock is released, and you don't need to release it manually (like you'd do for the mutexes).

  2. For Locks, you usually use a private object to lock (and should use).
    This is done for many reasons. (More info: see this answer and official documentation).

So, in case of locks, you can't (accidentally gain) access to the locked object from the outside and cause some damage.
But in case of Mutex, you can, as it's common to have a Mutex which is marked public and used from anywhere.

七七 2024-10-01 04:42:01

锁和监视器基本上用于为应用程序本身生成的线程(即内部线程)提供线程安全。另一方面,互斥体确保外部应用程序(即外部线程)生成的线程的线程安全。使用互斥体,只有一个外部线程可以在任何给定时间点访问我们的应用程序代码。

阅读本文

The Lock and Monitors are basically used to provide thread safety for threads that are generated by the application itself i.e. Internal Threads. On the other hand, Mutex ensures thread safety for threads that are generated by the external applications i.e. External Threads. Using Mutex, only one external thread can access our application code at any given point in time.

read this

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文