若有多个协程阻塞,如何保证只有⼀个协程被唤醒?

提问者:帅平 问题分类:面试刷题
Go语言互斥锁的问题,解锁后会发出信号量通知阻塞的协程:若有多个协程阻塞,如何保证只有⼀个协程被唤醒?若存在饥饿模式如何保证处于饥饿模式的协程优先获得锁?
1 个回答
烟波
烟波
1、在互斥锁的实现中,解锁后会发出信号量通知阻塞的协程,但是并不能保证只有一个协程被唤醒。多个协程可能同时被唤醒,然后竞争互斥锁。这是因为互斥锁的唤醒是由操作系统的调度器来控制的,调度器可能会同时唤醒多个协程。
2、为了确保只有一个协程被唤醒,可以结合条件变量(Cond)来实现。条件变量可以与互斥锁一起使用,通过条件变量的 Wait() 和 Signal() 或 Broadcast() 方法来实现协程的唤醒和等待。当互斥锁解锁时,可以使用条件变量的 Signal() 方法来唤醒一个协程,或使用 Broadcast() 方法唤醒所有协程。这样可以确保只有一个或一组协程被唤醒,其他协程仍然保持阻塞状态。
3、对于饥饿模式,可以使用公平锁(Fair Mutex)来解决。我在下面给你写了一个代码示例:我们自定义了一个 FairMutex 结构体,其中使用了 sync.Cond 来实现条件变量。公平锁会按照请求的顺序来分配锁,确保等待时间最长的协程优先获得锁,从而避免饥饿问题。
4、在 FairMutex 的 Lock() 方法中,使用了 for 循环来等待锁的释放,确保只有一个协程被唤醒。当锁被解锁时,使用条件变量的 Signal() 方法来唤醒一个协程,而其他协程仍然保持阻塞状态。
发布于:4周前 (04-22) IP属地:
我来回答