为什么我们需要在poll中调用poll_wait函数?

14

我在LDD3中看到了这些代码

static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
    struct scull_pipe *dev = filp->private_data;
    unsigned int mask = 0;

    /*
     * The buffer is circular; it is considered full
     * if "wp" is right behind "rp" and empty if the
     * two are equal.
     */
    down(&dev->sem);
    poll_wait(filp, &dev->inq,  wait);
    poll_wait(filp, &dev->outq, wait);
    if (dev->rp != dev->wp)
        mask |= POLLIN | POLLRDNORM;    /* readable */
    if (spacefree(dev))
        mask |= POLLOUT | POLLWRNORM;   /* writable */
    up(&dev->sem);
    return mask;
}

但是它说poll_wait不会等待并且会立即返回。那么为什么我们需要调用它?为什么不能只返回mask?

3个回答

19

poll_wait将您的设备(由“struct file”表示)添加到可以唤醒进程的列表中。

其思想是进程可以使用poll(或select或epoll等)将一堆文件描述符添加到希望等待的列表中。每个驱动程序的poll条目都会被调用,它们通过调用poll_wait方法将自己添加到等待列表中。

然后内核将阻塞该进程在一个位置。这样,任何一个设备都可以唤醒进程。如果返回非零掩码位,那意味着这些“准备就绪”的属性(可读/可写等)现在适用。

因此,伪代码大致如下:

foreach fd:
    find device corresponding to fd
    call device poll function to setup wait queues (with poll_wait) and to collect its "ready-now" mask

while time remaining in timeout and no devices are ready:
    sleep

return from system call (either due to timeout or to ready devices)

那么进程什么时候会休眠? - demonguy
你的意思是,用户空间中的轮询调用会阻塞进程,对吗? - demonguy
1
是的。当您在用户空间调用poll(2)时,它会进入内核中的一个名为“sys_poll”的函数(请参见内核源代码中的fs / select.c)。同样,select(2)=> sys_select等。所有这些函数都遵循我上面给出的伪代码。 - Gil Hamilton
我有一个问题:wait_queue_head_t是做什么的? void poll_wait (struct file *, wait_queue_head_t *, poll_table *); - Kevin Ding
1
这是一个数据结构,它锚定了“等待进程”队列的头部(在此设备内)。因此,如果发生传递数据(用于读取)或释放空间(用于写入)的中断,则设备可以通知核心内核,以便唤醒队列上的任何等待进程(这将导致每个进程被解除阻塞[调度运行],从而导致从进程所在队列中阻塞的select/poll系统调用返回到用户空间)。 - Gil Hamilton

3
< p > poll file_operation 如果返回 0 则会休眠

这就是让我感到困惑的事情。

当您返回非零值时,这意味着某些事件已触发,并唤醒其休眠。

一旦您看到这个,就清楚了,必须有某些东西将进程绑定到等待队列中,这个东西就是 poll_wait

还要记住, struct file 表示“进程和打开文件之间的连接”,不仅仅是文件系统文件,因此它包含用于标识进程的pid。

使用最小可运行示例进行实验也可能有助于澄清问题:https://dev59.com/ol0a5IYBdhLWcg3wsKi2#44645336


-2

当 poll_wait 在等待的任何 fd 上发生预期事件或超时时触发。

检查掩码以了解哪个事件触发了 poll_wait。如果您不希望 poll_wait 在此类事件上触发,则可以在向 poll fd 注册文件描述符时进行配置。


1
这完全是错误的。poll_wait根本不会“触发”。它只是将等待队列添加到poll_table中。 - EML

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接