公司网站首页怎么制作wordpress全站广告位
web/
2025/9/26 17:33:23/
文章来源:
公司网站首页怎么制作,wordpress全站广告位,wordpress slideshow,金华企业自助建站系统说起这个softirq #xff0c;很多人还是一头雾水#xff0c;觉得这个是什么东西#xff0c;跟tasklets 和 workqueue有什么不同。每次谈到这个#xff0c;很多人#xff0c;包括我#xff0c;都是有点紧张#xff0c;特别是面试的时候#xff0c;因为你一旦说错了什么很多人还是一头雾水觉得这个是什么东西跟tasklets 和 workqueue有什么不同。每次谈到这个很多人包括我都是有点紧张特别是面试的时候因为你一旦说错了什么那么你这次面试估计就歇菜了。谈到这个我们不得不说中断中断处理我相信很多人都是知道的中断分为上半部和下半部原来的Linux 内核是没有下半部的中断来了就在中断里处理事件说白了就是执行一些函数操作但是这个会导致一个问题就是系统调度慢了对于用户来说你用手机的时候感觉到十分卡顿真想摔了这个手机所以后来就出现了中断下半部。中断下半部的机制有很多种。例如softirq、tasklet、workqueue或是直接创建一个kernel thread来执行bottom half这在旧的kernel驱动中常见现在一个理智的driver厂商是不会这么做的tasklet 是基于softirq实现的所以我们讨论tasklet的时候其实也是在说softirq他们都是运行在中断上下文的。workqueue和softirq不同的是它运行是进程上下文。为什么需要这么多机制来实现中断下半部呢你可以理解我如果要去纽约我可以坐飞机可以坐轮船也可以开小汽车甚至我还可以骑自行车中断下半部也是一样tasklet的出现是因为把softirq封装起来更加方便别人使用。workqueue的话紧急程度就没有softirq那么紧急可以说优先级没有那么高如果是非常紧急的事情比如网络事件我们还是优先使用softirq来实现。Linux 内核里面可以有多少种softirq呢softirq是一种非常紧急的事件所以说不是你想用就用的内核里面定义了一个枚举变量来说明softirq支持的类型。/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high frequency threaded job scheduling. For almost all the purposes tasklets are more than enough. F.e. all serial device BHs et al. should be converted to tasklets, not to softirqs. */enum{ HI_SOFTIRQ0, TIMER_SOFTIRQ, NET_TX_SOFTIRQ, NET_RX_SOFTIRQ, BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on the numbering. Sigh! */ RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS};看到上面的那段英文了没它说「大部分情况下tasklets已经满足你的要求就不要只想着用softirq」软中断是什么时候执行的呢软中断和workqueue存在非常大的区别我们在上面说过软中断是在中断上下文的但是中断上半部已经脱离了中断了它如何跟中断上下文存在千丝万缕的联系呢说到这里我们不拿出代码来说那就是耍流氓了。/* * Exit an interrupt context. Process softirqs if needed and possible: */void irq_exit(void){#ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED local_irq_disable();#else WARN_ON_ONCE(!irqs_disabled());#endif account_irq_exit_time(current); preempt_count_sub(HARDIRQ_OFFSET); if (!in_interrupt() local_softirq_pending())//此处判断是否从中断上下文退出并判断是否有软中断任务挂起待处理 invoke_softirq();//启用排程软中断处理 tick_irq_exit(); rcu_irq_exit(); trace_hardirq_exit(); /* must be last! */}我们看看irq_exit()这个函数这个函数是在什么时候调用就是中断上半部执行结束后需要跳出中断上半部的时候我们需要执行irq_exit()然后在里面有一个判断。if (!in_interrupt() local_softirq_pending()) invoke_softirq(); tick_irq_exit(); rcu_irq_exit(); trace_hardirq_exit(); /* must be last! */}这几行代码就是判断当前是否需要执行软中断说白了就是CPU需要执行一段优先级非常高的代码这段代码需要在中断结束关闭中断后马上执行。#define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending)那我们在中断上半部执行结束后如何设置需要执行softirq呢使用这个函数#define set_softirq_pending(x) __this_cpu_write(irq_stat.__softirq_pending, (x))softirq相关的代码都在 softirq.c 这个文件里面如果想有更深入了解的同学可以一睹源码风采不吹C语言的源码真是一个宝藏细细评味可以挖掘出非常多的好东西。我们分析下 invoke_softirq这个函数是执行softirq的函数里面也有一些判断的东西我看了下源码理解了下顺便解读下自己的看法如果有疑问或者问题的请读者们指出来只有不断的探讨大家才可能收获更多的东西。static inline void invoke_softirq(void){ if (!force_irqthreads) {#ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK /* * We can safely execute softirq on the current stack if * it is the irq stack, because it should be near empty * at this stage. */ __do_softirq();#else /* * Otherwise, irq_exit() is called on the task stack that can * be potentially deep already. So call softirq in its own stack * to prevent from any overrun. */ do_softirq_own_stack();#endif } else { wakeup_softirqd(); }}不会看注释的码农不是好码农不写注释的码农就不是码农如果你想写代码就一定要会写注释同时你也要会看别人的注释好吧这类源码都是老外写的所以我们一定要习惯看英文注释慢慢看不要着急学会上下文推敲这样才像一个大神嘛。我不是大神所以我就瞎说一下上面使用一个 force_irqthreads 来区分一个东西就是软中断上下文软中断上下文是不能睡眠的你知道的你要是在中断里面睡眠那系统调度就起不来了起不来的原因那可真是五花八门因为你不知道进入中断的时候做了什么事情在中断里面的时候我们只有更高优先级的中断才能打断当前中断现在新版本的Linux内核取消了中断嵌套那你要是在中断里面睡觉就没有人叫你起床了那就只能出现panic挂机了。用我的话来说那就是睡死了。如果你的softirq里面执行很多东西在软中断上文没有执行完那你就需要用到软中断线程把剩下的事情做完然后就出现了wakeup_softirqd()这个就是处理软中断下半部的。看看__do_softirq()里面做的事情吧asmlinkage __visible void __softirq_entry __do_softirq(void){ unsigned long end jiffies MAX_SOFTIRQ_TIME; //最大处理时间2毫秒 unsigned long old_flags current-flags; int max_restart MAX_SOFTIRQ_RESTART; //最大回圈次数10次 struct softirq_action *h; bool in_hardirq; __u32 pending; int softirq_bit; /* * Mask out PF_MEMALLOC s current task context is borrowed for the * softirq. A softirq handled such as network RX might set PF_MEMALLOC * again if the socket is related to swap */ current-flags ~PF_MEMALLOC; pending local_softirq_pending(); //获取本地CPU上等待处理的软中断掩码 account_irq_enter_time(current); __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET); in_hardirq lockdep_softirq_start();restart: /* Reset the pending bitmask before enabling irqs */ set_softirq_pending(0); //清除本地CPU上等待处理的软中断掩码 local_irq_enable(); // 开中断状态下处理软中断 h softirq_vec; // h指向软中断处理函式阵列首元素 while ((softirq_bit ffs(pending))) { //依次处理软中断软中断编号越小越优先处理优先顺序越高 unsigned int vec_nr; int prev_count; h softirq_bit - 1; vec_nr h - softirq_vec; prev_count preempt_count(); kstat_incr_softirqs_this_cpu(vec_nr); trace_softirq_entry(vec_nr); h-action(h); //呼叫软中断回拨处理函式 trace_softirq_exit(vec_nr); if (unlikely(prev_count ! preempt_count())) { pr_err(huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n, vec_nr, softirq_to_name[vec_nr], h-action, prev_count, preempt_count()); preempt_count_set(prev_count); } //回圈下一个等待处理的软中断 h; pending softirq_bit; } rcu_bh_qs(); local_irq_disable(); //关中断判断在处理上次软中断期间硬中断处理函式是否又排程了软中断 pending local_softirq_pending(); if (pending) { //软中断再次被排程 if (time_before(jiffies, end) !need_resched() --max_restart) //没有达到超时时间也不需要被排程并且排程次数也没有超过10次 goto restart; //重新执行软中断 wakeup_softirqd(); //否则唤醒软中断核心执行绪处理剩下的软中断当前CPU退出软中断上下文 } lockdep_softirq_end(in_hardirq); account_irq_exit_time(current); __local_bh_enable(SOFTIRQ_OFFSET); WARN_ON_ONCE(in_interrupt()); current_restore_flags(old_flags, PF_MEMALLOC);}这段代码主要是展示了软中断上下文的处理策略一次处理所有等待的软中断处理轮训结束或者时间超过2ms就跳出软中断上下文跑到软中断线程里面去执行避免系统响应过慢。如何加入新的软中断说了那么多这个应该是重点了一直强调不要加软中断使用tasklet就够了但是无法避免就是有人要用啊。内核使用下面函数来新增一个软中断void open_softirq(int nr, void (*action)(struct softirq_action *)){ softirq_vec[nr].action action;}当然了你可以新增一个枚举变量内核里面是这样使用下面这个函数调用open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);好了就说这么多~右下角你懂的ʕ•̫͡•ʕ*̫͡*ʕ•͓͡•ʔ-̫͡-ʕ•̫͡•ʔ*̫͡*ʔ-̫͡-ʔ—————END—————扫码或长按关注回复「 加群 」进入技术群聊
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81459.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!