我正在创建一个允许访问系统范围共享资源的库,并希望在其上使用互斥锁。我过去曾使用Mutex
类来同步不同线程或进程中的操作。
在UI应用程序中可能会出现问题。我正在制作的库用于多个产品,其中一些是位于同一主机UI应用程序中的插件。因此,UI线程对于库的每个实例都是相同的 - 因此即使资源已被访问,mutex.WaitOne()
也将返回true。
'资源'是用户的注意力。我不希望打开多个特定的子窗口,无论哪个主机进程想要打开它。此外,它可能是一个不同的线程,知道何时可以释放互斥锁(子窗口关闭)。
是否有我可以申请的课程或模式,这将使我能够轻松解决这个问题?
总结一下我的意图,这可能是理想的虚构课程:
var specialMutex = new SpecialMutex("UserToastNotification");
specialMutex.WaitOne(0); // Returns true only once, even on the same thread,
// and is respected across different processes.
specialMutex.Release(); // Can be called from threads other than the one
// that called WaitOne();
是的,Release
看起来很危险,但只能由资源调用。
答案 0 :(得分:2)
我认为你想要一个初始值为1的Semaphore。WaitOne()
上对Semaphore
的任何调用都会尝试减少计数,无论线程如何。对Release
的任何调用,无论调用它的线程如何,都会导致计数递增。
因此,如果一个线程初始化一个值为1的信号量然后调用WaitOne
,则计数将变为0.如果同一个线程在同一个信号量上再次调用WaitOne
,则该线程将锁定等待释放。
其他一些主题可能会出现并调用Release
来增加计数。
所以,虽然Semaphore
并非与Mutex
完全相同,但它可能与您的程序有效相似。
答案 1 :(得分:-1)
您可以使用比较/交换操作来完成此操作。像这样:
class Lock {
int locked = 0;
bool Enter() { return Interlocked.CompareExchange(ref locked, 1, 0) == 0; }
void Leave() { Interlocked.CompareExchange(ref locked, 0, 1); }
}
在这里,Enter只会返回true一次,无论它被调用哪个线程,直到你调用leave。