Multithreading 如何在原子上下文中创建内核线程并多次使用[BUG:Scheduling while atomic]

Multithreading 如何在原子上下文中创建内核线程并多次使用[BUG:Scheduling while atomic],multithreading,linux-kernel,linux-device-driver,embedded-linux,atomic,Multithreading,Linux Kernel,Linux Device Driver,Embedded Linux,Atomic,我需要在驱动程序内核代码中运行kthread_。此线程倾向于在设备传输数据的位置打开/关闭LED。所以,基本上我不希望传输被放慢,因为LED闪烁的延迟时间。 我想在包传输代码的某个地方创建一个线程,以便该线程根据传输速率执行LED闪烁过程。 但是显然,在那里创建线程需要与线程调度程序交互,这在中断/原子上下文中是不允许的,并且会产生错误:在原子上下文中调度。根据我的研究,一种方法可能是在别处创建内核线程,并将中断请求处理排队给它。有人能再详细解释一下吗? 所以这不是我们有中断线程的情况。我基本上

我需要在驱动程序内核代码中运行kthread_。此线程倾向于在设备传输数据的位置打开/关闭LED。所以,基本上我不希望传输被放慢,因为LED闪烁的延迟时间。 我想在包传输代码的某个地方创建一个线程,以便该线程根据传输速率执行LED闪烁过程。 但是显然,在那里创建线程需要与线程调度程序交互,这在中断/原子上下文中是不允许的,并且会产生错误:在原子上下文中调度。根据我的研究,一种方法可能是在别处创建内核线程,并将中断请求处理排队给它。有人能再详细解释一下吗?
所以这不是我们有中断线程的情况。我基本上需要一个函数,它有自己的线程远离我的主线程。我会随时调用这个函数!如果还不清楚,请告诉我。谢谢。

您实际上并不需要内核线程。您需要一个工作队列。您可以从中断的上半部分对辅助函数进行排队,内核一有时间就会在进程上下文中运行它。如果可以避免睡眠,则可以通过函数
schedule\u work()
schedule\u delayed\u work()
使用共享队列

为避免睡眠,请将一个工作功能排队以打开LED。在该函数结束时,将延迟工作函数排队以将其关闭

如果你想做一个简单的
打开();睡眠();关闭()
,您需要在模块初始化时创建自己的工作队列,并使用
队列工作()
队列延迟工作()

参考:
实际上,您并不需要内核线程。您需要一个工作队列。您可以从中断的上半部分对辅助函数进行排队,内核一有时间就会在进程上下文中运行它。如果可以避免睡眠,则可以通过函数
schedule\u work()
schedule\u delayed\u work()
使用共享队列

为避免睡眠,请将一个工作功能排队以打开LED。在该函数结束时,将延迟工作函数排队以将其关闭

如果你想做一个简单的
打开();睡眠();关闭()
,您需要在模块初始化时创建自己的工作队列,并使用
队列工作()
队列延迟工作()

参考:

您不能使用内核内置的现有LED API吗?您不能使用内核内置的现有LED API吗?谢谢您的回复。那么这是否意味着在这种情况下使用kthread是一种错误的方法呢?好吧,工作队列实际上是将工作排队到内核线程,这正是您所要求的。kthread不是用于重复生成,而是用于设置一次。工作队列抽象是一种将小任务捆绑起来并要求内核在不同上下文中执行它的方法。Linux中几乎每个中断处理程序都有上半部分(快速中断上下文)和下半部分。通常,下半部分是工作队列函数。感谢您的回复。那么这是否意味着在这种情况下使用kthread是一种错误的方法呢?好吧,工作队列实际上是将工作排队到内核线程,这正是您所要求的。kthread不是用于重复生成,而是用于设置一次。工作队列抽象是一种将小任务捆绑起来并要求内核在不同上下文中执行它的方法。Linux中几乎每个中断处理程序都有上半部分(快速中断上下文)和下半部分。通常,下半部分是工作队列函数。