如何在场景后面实现epoll(),互斥和信号量系统调用?

时间:2016-12-15 02:36:34

标签: linux multithreading asynchronous linux-kernel operating-system

这真是一个令我困惑的问题。我试过google很多但仍然不太明白。我的问题是这样的:

对于epoll(),mutex和semaphore等系统调用,它们有一个共同点:一旦发生某些事情(以互斥为例,一个线程释放锁),然后一个线程被唤醒(该线程)等待锁定的人可以被唤醒。

我想知道这个机制(在一个线程中发生了一个事件,然后另一个线程被通知了)在场景后面实现了怎么样?我只想出两种方式:

  1. 硬件级别中断:例如,只要另一个线程释放锁定,就会发生边缘触发。
  2. 忙着等待:忙着等待很低的等级。例如,一旦另一个线程释放锁定,它将从0更改为1,以便等待锁定的线程可以检查此位。
  3. 我不确定我猜哪个是正确的。我想阅读linux源代码可以在这里提供帮助。但对我这样的菜鸟来说有点困难。这里有一个大致的想法加上一些伪代码会很棒。

1 个答案:

答案 0 :(得分:1)

Linux内核有一个内置的对象类叫做“等待队列”(其他操作系统有类似的机制)。为所有类型的“可等待”资源创建等待队列,因此内核中存在相当多的资源。当线程检测到它必须等待资源时,它会加入相关的等待队列。这个过程大致如下:

  1. Thread将其控制结构添加到与所需等待队列关联的链接列表中。
  2. 线程调用scheduler,它将调用线程标记为休眠状态,将其从“准备运行”列表中删除,并将其上下文隐藏在远离CPU的位置。然后,调度程序可以自由选择任何其他线程上下文来加载到CPU上。
  3. 当资源变得可用时,另一个线程(无论是用户/内核线程还是由中断处理程序调度的任务 - 那些通常搭载在特殊“工作队列”线程上的任务)调用相关的“唤醒”调用等待队列。 “唤醒”意味着,调度程序应从等待队列链表中删除一个或多个线程控制结构,并将所有这些线程添加到“准备运行”列表中,这将使它们能够在适当的时候进行调度。

    这里有一点技术概述: http://www.makelinux.net/ldd3/chp-6-sect-2