linux内核占用cpu过高,linux内核工作队列

第24 节解释了在处理中断时,Linux 内核将完整的中断处理分为“上半部分”和“下半部分”,以解决“想要更快地处理它们,但又想要多做。\’\’ ”。所有耗时但实时性要求不高的处理部分都放在下半部分。

Linux 内核2.6.26 版本具有三个“子部分”,分别为软中断、微线程和工作队列。前面两节主要讲了软中断和tasklet。由于软中断位于中断上下文中,因此软中断处理程序不能阻塞或休眠,我们已经知道这会限制软中断处理程序的性能。这同样适用于微线程,因为它们是基于Softirq 机制实现的。

Linux 内核中的工作队列如果您想将工作的后半部分推迟到进程上下文,或者需要休眠推迟的任务,则应该使用工作队列机制。 Linux 内核将工作队列中的工作传递给内核线程执行。内核线程在进程上下文中运行,允许工作队列重新调度和休眠。

工作队列子系统实际上是一组接口,通过这些接口创建进程(所谓的工作线程)来执行Linux内核或其他模块放入工作队列中的任务。 Linux内核提供了一个默认的工作线程(event/n,其中n是处理器编号)来处理队列中的任务。这样,一个工作队列就变成了一组移交给特定任务的延迟任务(排队任务)。用于处理的线程(默认工作线程)。 Linux内核工作队列中使用的数据结构是workqueue_struct结构。其C语言代码为:

struct workqueue_struct { struct cpu_workqueue_struct *cpu_wq; int singlethread; /* 挂起时冻结线程*/#ifdef struct lockdep_map lockdep_map;#endif};该struct是一个链表中的节点,成员cpu_wq是一个方面。由于每个处理器对应一个工作线程,因此结构体cpu_workqueue_struct的C语言代码为:请参阅。

struct cpu_workqueue_struct {spinlock_t lock; struct list_head_worklist; /* run_workqueue() 检测递归深度*/} 连接到____cacheline_struct 链表;每个工作线程都关联自己的工作队列wq,线程成员负责关联线程。

处理工作队列中的任务。结构体cpu_workqueue_struct的成员current_work表示工作线程正在处理的工作。它的数据结构由work_struct结构体定义。请参考以下内容。

struct work_struct {atomic_long_t data; struct list_headentry; work_func_t func;};成员func指向处理函数,data是其参数。这些结构体连接成链表,每个处理器上的每种类型的队列都对应这样一个链表。比如上面提到的“默认工作线程”就有这样一个链表。

当一个工作线程启动时,它会执行链表中的所有工作,并在完成后从链表中删除相应的work_struct。当链表为空时,工作线程再次进入休眠状态。这个过程是由worker_thread()函数完成的。其C语言代码为:请参阅。

第299章300章!kthread_Should_stop() || 315 list_empty(cwq-more_work, wait);|| 320 中断;|| cwq);|| 324 | 325 return 326 } for( ; ) 在无限循环中,work_thread() 函数将自身设置为TASK_INTERRUPTIBLE 状态,并将进程添加到等待队列中,否则等待结束。并调用run_workqueue()函数来执行链表中的工作。请参考以下内容。

run_workqueue()函数的C语言代码虽然较长,但逻辑并不复杂。只需将链表中的节点对象一一删除即可运行。我这里就不详细说了。现在我们了解了Linux内核是如何设计和实现工作队列的,接下来我们来看看如何使用它们。

使用工作队列Linux 内核定义了DECLARE_WORK 宏来静态创建一个work_struct 结构。其C语言代码为:

#define DECLARE_WORK(n, f) \\ struct work_struct n=__WORK_INITIALIZER(n, f) #define __WORK_INITIALIZER(n, f) { \\ .data=WORK_DATA_INIT(), \\ .entry={ (n).entry, (n) .entry }, \\ .func=(f), \\ __WORK_INIT_LOCKDEP_MAP(#n, (n)) \\}实际上,您将创建一个work_struct 结构并为其赋值。当然,你也可以在C语言程序运行时使用INIT_WORK宏通过指针来创建作业。 INIT_WORK宏的C语言代码为:

#define INIT_WORK(_work, _func) \\ do { \\ (_work)-data=(atomic_long_t) WORK_DATA_INIT() \\ INIT_LIST_HEAD((_work)-entry); (0) 我们看一下工作队列处理函数的原型。

void work_handler(void *data); 因为这个函数是由工作线程执行的,所以它运行在进程上下文中,可以响应中断,并且可以休眠和调度。创建作业后,可以通过schedule_work()函数将其传递给默认工作线程进行处理。其C语言代码为:

intSchedule_work(struct work_struct *work) { return queue_work(keventd_wq, work);} 这个动作很容易理解,因为schedule_work()函数实际上是添加到全局工作队列keventd_wq中。其C语言代码为:

int queue_work(struct workqueue_struct *wq, struct work_struct *work){ int ret=0; if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { BUG_ON(!list_empty(work-entry)), get_cpu(); ); put_cpu(); } return ret;} 容易看出queue_work()函数的核心功能是由__queue_work()函数完成的。它们如下:

此时,schedule_work()函数的关键其实就是将工作添加到工作队列中并等待执行。

当然,Linux内核允许你创建新的工作线程,但是不推荐这样做,所以我们把相关的分析留给你。至此,本节中我们已经完成了对Linux 内核“下半部分”中三种类型中断的高级分析。 “软中断”适用于频繁执行、实时性要求较高的处理任务,但必须保证共享数据的同步安全。 Tasklet可以防止同一类型的工作同时在多个处理器上执行,但它们是基于“软中断”实现的,因此它们处于像“软中断”这样的中断上下文中,不能休眠或阻塞。如果需要在流程上下文中执行延迟工作,则应选择工作队列。

欢迎大家在评论区讨论、提问。所有文章均为手写且原创(本文部分内容讨论Linux内核的原理和设计)。如果您喜欢我的文章,我会提供有关C、Linux 和其他嵌入式开发的每日报道。关注我们以查看最新更新和过去的文章。

本文和图片来自网络,不代表火豚游戏立场,如若侵权请联系我们删除:https://www.huotun.com/game/623134.html

(0)
上一篇 2024年5月27日
下一篇 2024年5月27日

相关推荐

  • 和平精英空投行动怎么下载?

    和平精英空投行动怎么下载? 和平精英空投行动是可以应用宝进行下载。和平精英的空头行动是最近的版本更新内容,需要在大版本进行游戏维护后更新完成的,新版本游戏之后,就可以在腾讯应用宝里面直接进行下载。保证内存空间充足后可以游玩。 和平精英家园空投箱怎么领最好? 关于这个问题,1. 每日签到:在和平精英游戏中每日签到可以获得一些家园空投箱。 2. 完成任务:在和平…

    游戏快讯 58分钟前
  • 和平精英丧尸克星怎么获得?

    和平精英丧尸克星怎么获得? 和平精英上10颗星勋章的话,你要参加现实的丧尸活动,才可以获得这个勋章的 和平精英丧尸模式怎么下载? 其实是国际服,可以在浏览器的官网下载 和平精英怎么变成丧尸猎人? 你需要活到最后两个人才能变成和平精英里的丧尸,猎人 和平精英丧尸危机怎么玩? 和平精英丧尸危机是一种多人合作的生存射击游戏。玩家需要组队与其他玩家一起合作,击败一波…

    游戏快讯 2小时前
  • 和平精英怎么刚枪? 和平精英怎么锁定城市刚枪?

    和平精英怎么刚枪? 和平精英刚枪的方法: 1.移动射击 2.掩体利用、左右探头 在掩体后重分利用左右探头的操作和第三人称的视野优势,可以借助于自己藏身的掩体或墙壁观察对手的走位。 3.提前枪。 和平精英怎么锁定城市刚枪? 点击左侧的模式选择区域。进入模式选择区域之后,在右下角战术选择的地方切换战术目标为“城区刚枪”。然后点击右下角确定即可。或者 步骤一,通过…

    游戏快讯 3小时前
  • 和平精英刚枪技巧口诀?

    和平精英刚枪技巧口诀? 你好,和平精英刚枪技巧口诀如下: 1. 瞄准稳定:在射击过程中,保持枪支的稳定是非常重要的。尽量减少手部的晃动,保持瞄准准心在目标上。 2. 控制后坐力:后坐力是影响枪支稳定的主要因素之一。通过适当的操作,尽量减少后坐力对瞄准的影响。 3. 弹道预判:了解不同枪械的子弹弹道特点,针对不同距离的目标进行预判,调整瞄准点。 4. 利用掩体…

    游戏快讯 5小时前
  • 和平精英怎么租号玩? 和平精英怎么用账号密码登其他号?

    和平精英怎么租号玩? 和平精英组号可以加入和平精英,做好群联系里面的管理员或群主,按每小时多少钱收费。 和平精英怎么用账号密码登其他号? 和平精英用账号密码登其他号的方法 1.想要登录别人的号,玩家只要获得别人的账号和密码,切换登录即可。 2.玩家进入游戏后找到右下方的齿轮状设置图标进入。 3.在页面的最下方可以找到退出登录按钮点击一下就可退出当前账号。 4…

    游戏快讯 6小时前