我正在扩展信号量的功能。当我意识到我不知道实际信号量的实现并确保我的代码正确运行时,我遇到了障碍,我需要知道这一点。
我知道信号量的工作原理是在调用 sem_wait() 并且另一个线程当前将其锁定时阻塞正在等待它的线程。然后线程被阻塞,然后被放入该信号量的等待列表中。
我的问题与 sem_post() 上发生的情况有关。下一个线程是否从等待列表中拉出,设置为锁定线程,并允许解除阻塞?或者发布的计划完全不同?
谢谢!
我正在扩展信号量的功能。当我意识到我不知道实际信号量的实现并确保我的代码正确运行时,我遇到了障碍,我需要知道这一点。
我知道信号量的工作原理是在调用 sem_wait() 并且另一个线程当前将其锁定时阻塞正在等待它的线程。然后线程被阻塞,然后被放入该信号量的等待列表中。
我的问题与 sem_post() 上发生的情况有关。下一个线程是否从等待列表中拉出,设置为锁定线程,并允许解除阻塞?或者发布的计划完全不同?
谢谢!
下一个要解除阻塞的sem_wait()
线程将是操作系统决定的下一个要上下文切换的线程。没有人对订购做出任何保证;这取决于您的操作系统的调度策略。它可能是离开 CPU 时间最长的线程,或者被分配了最高“优先级”的线程,或者历史上具有某些资源使用统计信息的线程,等等。
最有可能的是,您当前的线程(调用 的线程sem_post()
)将继续运行一段时间,直到它开始等待用户输入、阻塞另一个信号量或用完其操作系统分配的时间片。然后,操作系统将切换到一些完全不相关的进程以运行几分之一秒(可能是 Firefox 或其他东西),然后开始处理一些网络流量,给自己喝杯茶,最后,当它运行时对它,选择你感觉的任何其他线程,基于它是否基于过去的历史感觉特定线程更多地受 CPU 或 I/O 限制。
在许多操作系统中,优先考虑 I/O 绑定的进程,这些进程并没有出现很长时间。理论是新进程可能是短暂的(如果它已经存在了五个小时,那么它很可能不会在接下来的 1 毫秒内完成)所以我们不妨让它们结束。I/O-bound 进程很可能继续是 I/O-bound,这意味着它们很可能会在等待其他资源的同时很快关闭 CPU。基本上,操作系统希望找到它能够尽快完成的进程,这样它就可以重新喝茶并运行你的恶意软件。
信号量有两个操作:
P()
获取信号量(你似乎称之为sem_wait
)V()
释放信号量(你似乎称之为sem_post
)信号量也有一个与之相关的整数,即允许通过 P() 而不阻塞的并发线程数。对 P() 的其他调用将阻塞,直到调用 V() 以释放点。
这是信号量的经典定义。
编辑:信号量不保证任何顺序。他们不必实际使用队列或其他 FIFO 结构。当一次只允许一个线程时,当它调用 V() 时,另一个(可能是随机的)线程将从其 P() 调用返回并继续。