如何改变 Windows Mutex 的递归锁定行为?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1988324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:40:33  来源:igfitidea点击:

How to alter the recursive locking behaviour of Windows Mutex?

cwindowsposixmutex

提问by Jay

Windows Mutex seems to allow an acquired lock to be acquired again (recursively) if the thread currently owning the lock tries to acquire it.

如果当前拥有锁的线程尝试获取它,Windows Mutex 似乎允许再次(递归地)获取已获取的锁。

But, posix based pthread locks don't allow such a behaviour.

但是,基于 posix 的 pthread 锁不允许这种行为。

Is there any compile time macro or any settings which can make the windows mutex behave in the same way as the pthread mutex?

是否有任何编译时宏或任何设置可以使 windows 互斥锁的行为与 pthread 互斥锁的行为相同?

采纳答案by Hans Passant

As long as you program in Windows, avoid reimplementing the behavior of its Mutex. It being re-entrant by the same thread is absolutely essential for its defined behavior.

只要您在 Windows 中编程,请避免重新实现其 Mutex 的行为。它被同一个线程重入对于其定义的行为是绝对必要的。

A sync object without thread affinity is a semaphore that counts to 1. Use CreateSemaphore().

没有线程关联的同步对象是计数为 1 的信号量。使用 CreateSemaphore()。

Fwiw, it is very curious that you need this kind of behavior. It sounds like you are trying to use the same sync object in multiple places inappropriately. You can use the semaphore but you'll lose concurrency potential. Consider using more than one mutex instead.

Fwiw,很好奇你需要这种行为。听起来您正试图在多个地方不恰当地使用相同的同步对象。您可以使用信号量,但会失去并发潜力。考虑使用多个互斥锁。

回答by gavinb

You cannot alter the fact that Windows Mutexes are recursive. And while Posix threads are not recursive by default, you canuse pthread_mutexattr_settype()with the PTHREAD_MUTEX_RECURSIVEflag to make one so.

您无法改变 Windows 互斥体是递归的这一事实。虽然默认情况下 Posix 线程不是递归的,但您可以使用pthread_mutexattr_settype()PTHREAD_MUTEX_RECURSIVE标志来实现递归。

Locking a mutex in Windows is actually quite an expensive operation, and best suited to inter-process synchronisation. For a mutex used only within a single process, a critical section is normally used, however these are re-entrant also. As nobugz states, you would need to use a semaphore, initialised with a maximum count of 1, to get non-recursive synchronisation.

在 Windows 中锁定互斥锁实际上是一项非常昂贵的操作,最适合进程间同步。对于仅在单个进程中使用的互斥锁,通常使用临界区,但这些也是可重入的。正如 nobugz 所述,您需要使用一个信号量,初始化为最大计数为 1,以获得非递归同步。

A semaphore object is like a special counter, that can be atomically incremented and decremented across threads (or processes, if created shared). By creating one with a maximum count of 1, you get the non-recursive behaviour you require.

信号量对象就像一个特殊的计数器,它可以跨线程(或进程,如果创建共享)以原子方式递增和递减。通过创建最大计数为 1 的一个,您可以获得所需的非递归行为。

回答by Jér?me Pouiller

I suggest to use Read/Write locks (aka SRW). Like Windows Mutex, they are not recursive. Like Critical Sections, they are light and do not call kernel if they are free (Benchmarks).

我建议使用读/写锁(又名 SRW)。与 Windows Mutex 一样,它们不是递归的。像临界区一样,它们很轻,如果它们是免费的,就不会调用内核(基准)。

回答by Tony The Lion

Have a look at this article under 'fast mutex'.

'fast mutex'下查看这篇文章。

These type of mutexes cannot be recursively acquired.

这些类型的互斥锁不能递归获取。

Off course, you'd have to look into how to implement them in C.

当然,您必须研究如何在 C 中实现它们。