想象一下我有一个互斥锁。有无限数量的其他线程等待锁定互斥锁。当我解锁互斥锁时,将选择其中一个线程进入临界区。但是我无法控制哪一个。如果我想让特定线程进入临界区怎么办?
我很确定这不能使用 POSIX 互斥锁来完成,但是,我可以使用不同的同步对象来模拟行为吗?
想象一下我有一个互斥锁。有无限数量的其他线程等待锁定互斥锁。当我解锁互斥锁时,将选择其中一个线程进入临界区。但是我无法控制哪一个。如果我想让特定线程进入临界区怎么办?
我很确定这不能使用 POSIX 互斥锁来完成,但是,我可以使用不同的同步对象来模拟行为吗?
您可以使用互斥锁、条件变量和线程 ID 来实现。
在解锁互斥锁之前,线程设置目标线程ID,广播条件变量并释放互斥锁。等待线程唤醒,锁定互斥体并检查目标线程 id 是否等于该线程 id。如果不是,则线程返回等待。
为了避免唤醒所有等待线程只是为了检查目标线程 id 然后返回等待,对此方法的优化是为每个等待线程使用单独的条件变量。这样,信号线程将通知特定目标线程的条件变量。
另一种选择是使用发送到特定线程的信号。假设我们SIGRTMIN
用于此目的。首先,所有线程在开始时都会阻塞这个信号,这样信号就会处于未决状态并且不会在线程不等待它时丢失。当一个线程想要锁定互斥锁时,它首先调用sigwait()
它以原子方式解除阻塞SIGRTMIN
并等待它或交付一个已经挂起的互斥锁。一旦线程收到信号,它就可以继续并锁定互斥锁。信令线程用于pthread_kill(target_thread_id, SIGRTMIN)
唤醒特定线程。