我的编程空间,编程开发者的网络收藏夹
学习永远不晚

linux软中断和工作队列有什么用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

linux软中断和工作队列有什么用

这篇“linux软中断和工作队列有什么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“linux软中断和工作队列有什么用”文章吧。

linux中软中断和工作队列的作用是实现中断处理。软中断和工作队列是中断上下部机制中的下半部实现机制。软中断不能睡眠、不能阻塞、不能进程间切换,只能被硬件中断打断;而工作队列可以睡眠,也能被阻塞,能够在不同的进程间切换,以完成不同的工作。

本教程操作环境:linux5.9.8系统、Dell G3电脑。

linux中软中断和工作队列的作用是实现中断处理。

1.中断概念

中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务的程序中去,服务完毕后再返回去继续运行被暂时中断的程序。Linux中通常分为外部中断(又叫硬件中断)和内部中断(又叫异常)。

在实地址模式中,CPU把内存中从0开始的1KB空间作为一个中断向量表。表中的每一项占4个字节。但是在保护模式中,有这4个字节的表项构成的中断向量表不满足实际需求,于是根据反映模式切换的信息和偏移量的足够使得中断向量表的表项由8个字节组成,而中断向量表也叫做了中断描述符表(IDT)。在CPU中增加了一个用来描述中断描述符表寄存器(IDTR),用来保存中断描述符表的起始地址。

2. Linux中断处理

2.1 系统中断号

  由上述中断定义可知,系统中断向量表中共可保存256个中断向量入口,即IDT中包含的256个中断描述符(对应256个中断向量)。

  而0-31号中断向量被intel公司保留用来处理异常事件,不能另作它用。对这 0-31号中断向量,操作系统只需提供异常的处理程序,当产生一个异常时,处理机就会自动把控制转移到相应的处理程序的入口,运行相应的处理程序;而事实 上,对于这32个处理异常的中断向量,2.6版本的 Linux只提供了0-17号中断向量的处理程序,其对应处理程序参见下表、中断向量和异常事件对应表;也就是说,17-31号中断向量是空着未用的。

中断向量号异常事件Linux的处理程序
0除法错误pide_error
1调试异常Debug
2NMI中断Nmi
3单字节,int 3Int3
4溢出Overflow
5边界监测中断Bounds
6无效操作码Invalid_op
7设备不可用Device_not_available
8双重故障Double_fault
9协处理器段溢出Coprocessor_segment_overrun
10无效TSSIncalid_tss
11缺段中断Segment_not_present
12堆栈异常Stack_segment
13一般保护异常General_protection
14页异常Page_fault
15(intel保留)Spurious_interrupt_bug
16协处理器出错Coprocessor_error
17对齐检查中断Alignment_check

  0-31号中断向量已被保留,那么剩下32-255共224个中断向量可用。 这224个中断向量又是怎么分配的呢?2.6版本的Linux中,除了0x80 (SYSCALL_VECTOR)用作系统调用总入口之外,其他都用在外部硬件中断源上,其中包括可编程中断控制器8259A的15个irq;事实上,当 没有定义CONFIG_X86_IO_APIC时,其他223(除0x80外)个中断向量,只利用了从32号开始的15个,其它208个空着未用。

 2.2 中断请求

  2.2.1 中断请求概述

  外部设备当需要操作系统做相关的事情的时候,会产生相应的中断。

  设备通过相应的中断线向中断控制器发送高电平以产生中断信号,而操作系统则会从中断控制器的状态位取得那根中断线上产生的中断。而且只有在设备在对某一条中断线拥有控制权,才可以向这条中断线上发送信号。也由于现在的外设越来越多,中断线又是很宝贵的资源不可能被一一对应。因此在使用中断线前,就得对相应的中断线进行申请。无论采用共享中断方式还是独占一个中断,申请过程都是先讲所有的中断线进行扫描,得出哪些没有别占用,从其中选择一个作为该设备的IRQ。其次,通过中断申请函数申请相应的IRQ。最后,根据申请结果查看中断是否能够被执行。

  2.2.2 中断相关结构

  中断中核心处理数据结构为irq_desc,它完整的描述了一条中断线,Linux 2.6。22.6中源码如下。

  irq_desc定义在include/linux/irq.h中

struct irq_desc {    irq_flow_handler_t    handle_irq;    struct irq_chip        *chip;    struct msi_desc        *msi_desc;    void            *handler_data;    void            *chip_data;    struct irqaction    *action;        unsigned int        status;            unsigned int        depth;            unsigned int        wake_depth;        unsigned int        irq_count;        unsigned int        irqs_unhandled;    spinlock_t        lock;#ifdef CONFIG_SMP    cpumask_t        affinity;    unsigned int        cpu;#endif#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)    cpumask_t        pending_mask;#endif#ifdef CONFIG_PROC_FS    struct proc_dir_entry    *dir;#endif    const char        *name;} ____cacheline_internodealigned_in_smp;

irq_desc

  其相关联的几个结构体如下:

  定义在include/linux/ interrupt.h中的中断行动结构体:struct irqaction

struct irqaction {    irq_handler_t handler;    unsigned long flags;    cpumask_t mask;    const char *name;    void *dev_id;    struct irqaction *next;    int irq;    struct proc_dir_entry *dir;};

  定义在include/linux 中的:irq_chip 芯片相关的处理函数集合

struct irq_chip {    const char    *name;    unsigned int    (*startup)(unsigned int irq);  //中断开始    void        (*shutdown)(unsigned int irq);    //中断关闭    void        (*enable)(unsigned int irq);      //中断使能    void        (*disable)(unsigned int irq);    //中断禁用    void        (*ack)(unsigned int irq);    void        (*mask)(unsigned int irq);    void        (*mask_ack)(unsigned int irq);    void        (*unmask)(unsigned int irq);    void        (*eoi)(unsigned int irq);    void        (*end)(unsigned int irq);    void        (*set_affinity)(unsigned int irq, cpumask_t dest);    int        (*retrigger)(unsigned int irq);    int        (*set_type)(unsigned int irq, unsigned int flow_type);    int        (*set_wake)(unsigned int irq, unsigned int on);    #ifdef CONFIG_IRQ_RELEASE_METHOD    void        (*release)(unsigned int irq, void *dev_id);#endif        const char    *typename;};

2.2.3 中断请求实现

上下半部机制

  我们期望让中断处理程序运行得快,并想让它完成的工作量多,这两个目标相互制约,如何解决——上下半部机制。

  我们把中断处理切为两半。中断处理程序是上半部——接受中断,他就立即开始执行,但只有做严格时限的工作。能够被允许稍后完成的工作会推迟到下半部去,此后,在合适的时机,下半部会被开终端执行。上半部简单快速,执行时禁止一些或者全部中断。

  下半部稍后执行,而且执行期间可以响应所有的中断。这种设计可以使系统处于中断屏蔽状态的时间尽可能的短,以此来提高系统的响应能力。上半部只有中断处理程序机制,而下半部的实现有软中断实现,tasklet实现和工作队列实现。

  我们用网卡来解释一下这两半。当网卡接受到数据包时,通知内核,触发中断,所谓的上半部就是,及时读取数据包到内存,防止因为延迟导致丢失,这是很急迫的工作。读到内存后,对这些数据的处理不再紧迫,此时内核可以去执行中断前运行的程序,而对网络数据包的处理则交给下半部处理。

上下半部划分原则

  1) 如果一个任务对时间非常敏感,将其放在中断处理程序中执行;

  2) 如果一个任务和硬件有关,将其放在中断处理程序中执行;

  3) 如果一个任务要保证不被其他中断打断,将其放在中断处理程序中执行;

  4) 其他所有任务,考虑放置在下半部执行。

下半部实现机制之软中断

  软中断作为下半部机制的代表,是随着SMP(share memory processor)的出现应运而生的,它也是tasklet实现的基础(tasklet实际上只是在软中断的基础上添加了一定的机制)。软中断一般是“可延迟函数”的总称,有时候也包括了tasklet(请读者在遇到的时候根据上下文推断是否包含tasklet)。它的出现就是因为要满足上面所提出的上半部和下半部的区别,使得对时间不敏感的任务延后执行,软中断执行中断处理程序留给它去完成的剩余任务,而且可以在多个CPU上并行执行,使得总的系统效率可以更高。它的特性包括:

  a)产生后并不是马上可以执行,必须要等待内核的调度才能执行。软中断不能被自己打断,只能被硬件中断打断(上半部)。

  b)可以并发运行在多个CPU上(即使同一类型的也可以)。所以软中断必须设计为可重入的函数(允许多个CPU同时操作),因此也需要使用自旋锁来保护其数据结构。

下半部实现机制之tasklet

  tasklet是通过软中断实现的,所以它本身也是软中断。

  软中断用轮询的方式处理。假如正好是最后一种中断,则必须循环完所有的中断类型,才能最终执行对应的处理函数。显然当年开发人员为了保证轮询的效率,于是限制中断个数为32个。

  为了提高中断处理数量,顺道改进处理效率,于是产生了tasklet机制。

  Tasklet采用无差别的队列机制,有中断时才执行,免去了循环查表之苦。Tasklet作为一种新机制,显然可以承担更多的优点。正好这时候SMP越来越火了,因此又在tasklet中加入了SMP机制,保证同种中断只能在一个cpu上执行。在软中断时代,显然没有这种考虑。因此同一种软中断可以在两个cpu上同时执行,很可能造成冲突。

  总结下tasklet的优点:

  (1)无类型数量限制;

  (2)效率高,无需循环查表;

  (3)支持SMP机制;

  它的特性如下:

  1)一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行执行。

  2)多个不同类型的tasklet可以并行在多个CPU上。

  3)软中断是静态分配的,在内核编译好之后,就不能改变。但tasklet就灵活许多,可以在运行时改变(比如添加模块时)。

下半部实现机制之工作队列(work queue)

  上面我们介绍的可延迟函数运行在中断上下文中(软中断的一个检查点就是do_IRQ退出的时候),于是导致了一些问题:软中断不能睡眠、不能阻塞。由于中断上下文出于内核态,没有进程切换,所以如果软中断一旦睡眠或者阻塞,将无法退出这种状态,导致内核会整个僵死。但可阻塞函数不能用在中断上下文中实现,必须要运行在进程上下文中,例如访问磁盘数据块的函数。因此,可阻塞函数不能用软中断来实现。但是它们往往又具有可延迟的特性。

  上面我们介绍的可延迟函数运行在中断上下文中,于是导致了一些问题,说明它们不可挂起,也就是说软中断不能睡眠、不能阻塞,原因是由于中断上下文出于内核态,没有进程切换,所以如果软中断一旦睡眠或者阻塞,将无法退出这种状态,导致内核会整个僵死。因此,可阻塞函数不能用软中断来实现。但是它们往往又具有可延迟的特性。而且由于是串行执行,因此只要有一个处理时间较长,则会导致其他中断响应的延迟。为了完成这些不可能完成的任务,于是出现了工作队列,它能够在不同的进程间切换,以完成不同的工作。

  如果推后执行的任务需要睡眠,那么就选择工作队列,如果不需要睡眠,那么就选择软中断或tasklet。工作队列能运行在进程上下文,它将工作托付给一个内核线程。工作队列说白了就是一组内核线程,作为中断守护线程来使用。多个中断可以放在一个线程中,也可以每个中断分配一个线程。我们用结构体workqueue_struct表示工作者线程,工作者线程是用内核线程实现的。而工作者线程是如何执行被推后的工作——有这样一个链表,它由结构体work_struct组成,而这个work_struct则描述了一个工作,一旦这个工作被执行完,相应的work_struct对象就从链表上移去,当链表上不再有对象时,工作者线程就会继续休眠。因为工作队列是线程,所以我们可以使用所有可以在线程中使用的方法。

Linux软中断和工作队列的作用是什么

linux 中的软中断和工作队列的作用是实现中断处理;它们是中断上下部机制中的下半部实现机制。

  1.软中断一般是“可延迟函数”的总称,它不能睡眠,不能阻塞,它处于中断上下文,不能进程间切换,软中断不能被自己打断,只能被硬件中断打断(上半部),可以并发的运行在多个CPU上。所以软中断必须设计成可重入的函数,因此也需要自旋锁来保护其数据结构。

  2.工作队列中的函数处在进程上下文中,它可以睡眠,也能被阻塞,能够在不同的进程间切换,以完成不同的工作。

可延迟函数和工作队列都不能访问用户的进程空间,可延时函数在执行时不可能有任何正在运行的进程,工作队列的函数有内核进程执行,他不能访问用户空间地址。

以上就是关于“linux软中断和工作队列有什么用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

linux软中断和工作队列有什么用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

linux软中断和工作队列有什么用

这篇“linux软中断和工作队列有什么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“linux软中断和工作队列有什么用”文
2023-06-30

laravel队列有什么作用

这篇文章主要介绍了laravel队列有什么作用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇laravel队列有什么作用文章都会有所收获,下面我们一起来看看吧。在laravel中,队列可以用于允许在表的前端进行
2023-07-02

linux工作列队的应用场景有哪些

Linux工作列队(job queue)的应用场景有很多,包括但不限于以下几个方面:1. 作业调度:Linux工作列队可用于作业调度,将多个作业按照优先级和资源需求等要求进行排序和调度,使得任务能够按照合理的顺序执行。2. 批量处理:Lin
2023-09-14

C++中队列有什么用

这篇文章主要介绍C++中队列有什么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 队列的概念及结构队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First
2023-06-25

CRM中间件里的CSA队列有什么作用

本篇内容主要讲解“CRM中间件里的CSA队列有什么作用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“CRM中间件里的CSA队列有什么作用”吧!我们有时候会在中间件的事务码SMQ2即Inbound
2023-06-04

Java中栈和队列有什么区别

这期内容当中小编将会给大家带来有关Java中栈和队列有什么区别,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面
2023-06-14

Java中消息队列的作用是什么

这篇文章主要讲解了“Java中消息队列的作用是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中消息队列的作用是什么”吧!1、 这些接口之间耦合比较严重,每新增一个下游功能,都要
2023-06-16

linux ttyload工具有什么作用

本文小编为大家详细介绍“linux ttyload工具有什么作用”,内容详细,步骤清晰,细节处理妥当,希望这篇“linux ttyload工具有什么作用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
2023-02-15

PHP中的多进程消费队列有什么用

小编给大家分享一下PHP中的多进程消费队列有什么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!最近开发一个小功能,用到了队列mcq,启动一个进程消费队列数据,后边发现一个进程处理不过来了,又加了一个进程,过了段时间又处理
2023-06-06

java序列化和反序列化有什么作用

Java的序列化和反序列化主要用于以下几个方面:1. 数据持久化:可以将Java对象转化为字节序列,并将其写入文件或者数据库,从而实现对象的持久化存储。2. 网络传输:在网络传输过程中,可以将Java对象序列化成字节序列,在网络中传输,接收
2023-09-25

linux中EncryptPad有什么作用

这篇文章主要介绍“linux中EncryptPad有什么作用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“linux中EncryptPad有什么作用”文章能帮助大家解决问题。
2023-02-17

linux中dd有什么作用

这篇文章主要介绍“linux中dd有什么作用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“linux中dd有什么作用”文章能帮助大家解决问题。在linux中,dd是用于读取、转换并输出数据的命令;该
2023-07-02

linux中shell有什么作用

Shell是一种命令行解释器,它是Linux操作系统中用户与系统内核交互的界面。它具有以下作用:1. 执行命令:通过Shell,用户可以输入各种命令来执行各种任务,例如创建、删除、移动文件和目录,运行程序,设置环境变量等。2. 脚本编程:S
2023-08-30

linux中cTop工具有什么用

这篇文章主要介绍linux中cTop工具有什么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么是 cTopctop 为多个容器提供了一个简洁凝练的实时指标概览。它是一个类 top 的针对容器指标的界面。它展示了容
2023-06-16

Cassandra中的分区键和聚簇列有什么作用

在Cassandra中,分区键和聚簇列都是用来定义数据模型和数据分布的重要概念。分区键:分区键是用来划分数据的主要依据,它决定了数据如何在集群中分布。数据被根据分区键进行分片,每个分片会被放置在集群中的不同节点上。通过选择合适的分区键,可以
Cassandra中的分区键和聚簇列有什么作用
2024-04-09

硬防和软防有什么作用

硬防和软防是网络安全中常用的两种防御手段。硬防指的是通过硬件设备和技术来保护网络安全。硬件设备包括防火墙、入侵检测系统(IDS)和入侵防御系统(IPS)等,这些设备可以检测和阻止网络攻击,提供基本的网络安全防护。硬防可以提供实时的网络监控和
2023-09-09

Linux Shell中()、(())、[]、[[]]、{}的有什么作用

这篇文章主要介绍“Linux Shell中()、(())、[]、[[]]、{}的有什么作用”,在日常操作中,相信很多人在Linux Shell中()、(())、[]、[[]]、{}的有什么作用问题上存在疑惑,小编查阅了各式资料,整理出简单好
2023-06-15

linux中的lo有什么作用

本篇内容主要讲解“linux中的lo有什么作用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux中的lo有什么作用”吧!在linux中,lo是local的简写,是指本地环回接口;利用这个接
2023-06-29

编程热搜

目录