在设备驱动程序中调用 set_current_state()/wait_event() 等睡眠函数的效果?
Effects of calling sleep functions like set_current_state()/wait_event() in a device driver?
我对内核模块加载到内核后的工作方式有点困惑,主要是因为睡眠函数调用。
以字符设备驱动程序为例,我在 read() 函数中看到如下代码,它试图使用 set_current_state()
(或者有时,wait_event_interruptible()
等):
set_current_state(TASK_INTERRUPTIBLE);
task = current;
for(;;)
{
if(condition)
break;
schedule();
}
set_current_state(TASK_RUNNING);
在写函数或中断处理程序中,他们试图通过将条件设置为真来唤醒 read(),如下所示:
condition = true;
wake_up_process(task); // -> task was stored inside read() function
我的问题是:
set_current_state()
或 wait_event_interruptible()
哪个 'process' 在这里睡觉?是调用系统调用 read() 的用户 space 进程还是为映射用户 space 进程而创建的某个内核进程?
假设通过在 open() 函数中设置原子计数,此设备驱动程序访问仅限于一个进程,并且设备驱动程序未启用中断,如果 read() 调用 wait_event() 还有没有别的进程居然可以唤醒它?它会永远卡住吗(因为没有可中断的)?
使用 set_current_state()
和 wait_event()
API 有什么区别?我已经看到不同的代码片段相应地使用了这些函数……我应该考虑对其中一个的偏好吗?
内核代码在发出系统调用的用户space线程的"kernel side"上下文中执行。每个 userspace 线程都有这样的 kernel-space 对应物。从调度器的角度来看,线程的用户部分和内核部分是同一个实体,因此当内核线程被调度出去时,用户线程也是如此。
"Interruptible" 和 "Non-interruptible" 等待信号的处理方式不同。当进程处于 TASK_INTERRUPTIBLE 状态并收到信号时,系统会确保它尽快从 schedule() 唤醒。之后,如果 signal_pending() returns 为真,进程本身必须离开等待循环。在问题文本中的示例代码中,除非 'condition' 是包含 signal_pending() check.
的表达式,否则无法正确实现
set_current_state() 是对当前进程状态的 setter 调用,它只是设置一个标志,不做任何其他事情。它只能与对 schedule() 的正确调用一起使用。
wait_event() 是一个实现所有等待技术细节的实用程序。通常,驱动程序使用 wait_event*() 风格,仅在特殊情况下才需要直接使用 set_current_state() 和 schedule()。
我对内核模块加载到内核后的工作方式有点困惑,主要是因为睡眠函数调用。
以字符设备驱动程序为例,我在 read() 函数中看到如下代码,它试图使用 set_current_state()
(或者有时,wait_event_interruptible()
等):
set_current_state(TASK_INTERRUPTIBLE);
task = current;
for(;;)
{
if(condition)
break;
schedule();
}
set_current_state(TASK_RUNNING);
在写函数或中断处理程序中,他们试图通过将条件设置为真来唤醒 read(),如下所示:
condition = true;
wake_up_process(task); // -> task was stored inside read() function
我的问题是:
set_current_state()
或wait_event_interruptible()
哪个 'process' 在这里睡觉?是调用系统调用 read() 的用户 space 进程还是为映射用户 space 进程而创建的某个内核进程?假设通过在 open() 函数中设置原子计数,此设备驱动程序访问仅限于一个进程,并且设备驱动程序未启用中断,如果 read() 调用 wait_event() 还有没有别的进程居然可以唤醒它?它会永远卡住吗(因为没有可中断的)?
使用
set_current_state()
和wait_event()
API 有什么区别?我已经看到不同的代码片段相应地使用了这些函数……我应该考虑对其中一个的偏好吗?
内核代码在发出系统调用的用户space线程的"kernel side"上下文中执行。每个 userspace 线程都有这样的 kernel-space 对应物。从调度器的角度来看,线程的用户部分和内核部分是同一个实体,因此当内核线程被调度出去时,用户线程也是如此。
"Interruptible" 和 "Non-interruptible" 等待信号的处理方式不同。当进程处于 TASK_INTERRUPTIBLE 状态并收到信号时,系统会确保它尽快从 schedule() 唤醒。之后,如果 signal_pending() returns 为真,进程本身必须离开等待循环。在问题文本中的示例代码中,除非 'condition' 是包含 signal_pending() check.
的表达式,否则无法正确实现
set_current_state() 是对当前进程状态的 setter 调用,它只是设置一个标志,不做任何其他事情。它只能与对 schedule() 的正确调用一起使用。 wait_event() 是一个实现所有等待技术细节的实用程序。通常,驱动程序使用 wait_event*() 风格,仅在特殊情况下才需要直接使用 set_current_state() 和 schedule()。