Multithreading 为什么内核会用另一个线程调度irq处理程序?

Multithreading 为什么内核会用另一个线程调度irq处理程序?,multithreading,linux-kernel,Multithreading,Linux Kernel,我在linux中使用irq处理程序时遇到了一个问题 我向请求注册一个处理程序\u irq 当外部硬件发送中断时可以调用 在irq处理程序中,代码编程如下: irqreturn_t irq_test_handler(int irq, void *desc) { wake_up_process(a_thread_handle); mdelay(10); printk("end the handler\n"); return IRQ_HANDLED; } 一个线程句柄来自函数:kthread\u c

我在linux中使用irq处理程序时遇到了一个问题

我向请求注册一个处理程序\u irq

当外部硬件发送中断时可以调用

在irq处理程序中,代码编程如下:

irqreturn_t irq_test_handler(int irq, void *desc)
{
wake_up_process(a_thread_handle);
mdelay(10);
printk("end the handler\n");
return IRQ_HANDLED;
}
一个线程句柄来自函数:kthread\u create(一个线程…)

所以在我看来,当irq发生时

它将像这样打印

"

结束处理程序

在kthread中

"

但事实上,

它将这样打印:

"

在kthread中

结束处理程序

"


有人能给我解释一下吗?

通过
唤醒过程()
你想要做的就是
请求线程化的irq()
所提供的。调用
request\u irq()
request\u-threaded\u irq()
相同,但使用
thread\u fn=NULL
。如果提供线程并返回
IRQ\u WAKE\u thread
,则处理程序函数完成后,线程将被唤醒。我认为这是你的初衷(见附件)

若要尝试使用多核效果,请将系统设置为单核

#!/usr/bin/sudo bash
CPU_DIR="/sys/devices/system/cpu"
NEXT=$(( 1 - $( cat ${CPU_DIR}/cpu1/online ) ))
for d in /sys/devices/system/cpu/cpu*
do
  CPU=${d##*/}
  if [ ${CPU} == "cpuidle" ]; then continue; fi
  if [ ${CPU} == "cpu0" ]; then continue; fi
  echo -n $CPU $( cat $d/online )
  echo "${NEXT}" >$d/online
  echo " => " $( cat $d/online )
done
然后再试一次。第一个呼叫是单核,第二个呼叫是回拨。您还可以使用内核参数
nosmp
maxcpus=0
重新启动,以完全禁用SMP激活(请参阅)


仅用于文档说明(请参阅下面的注释):这是一种多核效果,线程运行在不同的核心上,因此立即启动。

如果您唤醒一个进程,然后等待(在IRQ处理程序中!糟糕!),为什么您希望顺序是“处理程序,进程”而不是“进程,处理程序”?此外,请使用适当的大小写(大写/小写);这听起来很糟糕,因为我们遇到了一个非常低的问题——唤醒线程比irq处理程序先运行,所以我们只是测试这个问题是否会以这种方式发生。当然,这只是为了测试,因为这样做太愚蠢了;^^!irq处理程序必须比进程先运行,对吗?irq处理程序确实先运行;IRQ处理程序通常在一个CPU上执行,但线程
a_kthread
在另一个CPU上执行。所以处理程序不会阻止线程的执行。你的意思是,当它在irq处理程序中时,它将由内核调度?你能给我看一下密码吗?谢谢你的回答。内核中的mdelay函数只是让cpu等待,不像sleep函数那样。我把它放在irq处理程序的顶部,在我看来,在它完成irq处理程序之前,我不会安排另一个线程。你能展示一些代码来展示这个时间表吗?SA_中断是什么意思?我使用代码请求一个irq:ret=request\u irq(g\u irq,irq\u test\u handler,4,“myirq”,NULL);中断处理是由实际响应硬件中断的上半部分(即“硬”irq)和由上半部分安排进行额外处理的下半部分(或“软”irq)完成的。上半部分在中断被禁用的情况下执行,因此必须尽可能少地保持系统响应我把代码放在上半部分,所以这部分不应该安排。我不知道我的意见是否正确。如果使用
request\u irq()
,上半部分是处理程序
handler
,下半部分是内核线程
thread\u fn
,它是
NULL
。因此,不要使用
wake\u-up\u-process()
,而是使用
request\u-threaded\u-irq()
。谢谢,现在我的问题是为什么要安排它。当然,有很多方法可以达到我的目标。但是从内核irq的设计来看,我想知道为什么会发生这种情况。
#!/usr/bin/sudo bash
CPU_DIR="/sys/devices/system/cpu"
NEXT=$(( 1 - $( cat ${CPU_DIR}/cpu1/online ) ))
for d in /sys/devices/system/cpu/cpu*
do
  CPU=${d##*/}
  if [ ${CPU} == "cpuidle" ]; then continue; fi
  if [ ${CPU} == "cpu0" ]; then continue; fi
  echo -n $CPU $( cat $d/online )
  echo "${NEXT}" >$d/online
  echo " => " $( cat $d/online )
done