精华内容
下载资源
问答
  • linux软中断
    2021-05-10 08:14:47

    Linux软中断通信实验报告

    实验2 Linux软中断通信

    1.实验目的

    通过本实验,掌握软中断的基本原理;掌握中断信号的使用、进程的创建以及系统计时器的使用。

    2.实验内容(上交的实验2统一取名为:test2

    由父进程创建两个子进程,通过终端输入Crtl+\组合键向父进程发送SIGQUIT软中断信号或由系统时钟产生SIGALRM软中断信号发送给父进程;父进程接受到这两个软中断的其中某一个后,向其两个子进程分别发送整数值为16和17软中断信号,子进程获得对应软中断信号后,终止运行;父进程调用wait 函数等待两个子进程终止,然后自我终止。

    3. 设计思想及算法流程

    4. 源程序

    #include

    #include

    #include

    #include

    #define SEC 5

    void waiting ;

    void stop ;

    int wait_mark;

    int main int p1, p2; /*定义两个进程号变量*/

    while p1 fork -1 ; /*循环创建进程至成功为止*/

    if p1 0 while p2 fork -1 ; /*循环创建进程至成功为止*/ if p2 0 wait_mark 1; alarm SEC ; signal SIGQUIT, stop ; signal SIGALRM, stop ; waiting ; kill p1, 16 ; kill p2, 17 ; wait 0 ; wait 0 ; printf "Parent process is killed!\n" ; exit 0 ; else signal SIGQUIT, SIG_IGN ; signal SIGALRM, SIG_IGN ; wait_mark 1; signal 17, stop ; /*接收到软中断信号17,转stop*/ waiting ; /*在wait置0前,不可往下执行*/ lockf 1, 1, 0 ; /*加锁*/ printf "Child process 2 is killed by parent!\n" ; lockf 1, 0, 0 ; /*解锁*/ exit 0 ; /*子进程2退出*/ else signal SIGQUIT, SIG_IGN ; signal SIGALRM, SIG_IGN ; wait_mark 1; /*将等待标记置1直到中断信号刺激stop*/ signal 16, stop ; /*接收到软中断信号16,转stop*/ waiting ; /*在wait置0前,不可往下执行*/ lockf 1, 1, 0 ; printf "Child process 1 is killed by parent!\n" ;/*接收到父进程发送信号后,父进程杀死子进程1*/ lockf 1, 0, 0 ; /*解锁*/ exit 0 ; /*子进程1退出*/ return 0; void waiting while wait_mark ! 0 ; void stop wait_mark 0; 5.运行结果

    Fork函数建立两个子进程,p1,p2

    是否成功

    分别向p1,p2,发出16,17信号

    等待SIGQUIT信号

    P1,p2进程运行

    等待16,17信号

    开始

    显示结果,发出结束信号

    等待p1,p2结束信号

    显示结果

    结束

    N

    Y

    N

    Y

    Y

    Y

    N

    N

    N

    更多相关内容
  • 实验2 Linux软中断通信 1.实验目的 通过本实验掌握软中断的基本原理掌握中断信号的使用进程的创建以及系统计时器的使用 2.实验内容上交的实验2统一取名为test2) 由父进程创建两个子进程通过终端输入Crtl+\组合键向父...
  • linux 软中断

    2021-02-20 12:39:16
    文章目录系列文章目录前言一、什么是软中断?二、查看软中断和内核线程总结 前言 说到中断,简单说过中断的含义,先来回顾一下。中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后...

    系列文章目录


    前言

    说到中断,简单说过中断的含义,先来回顾一下。中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来响应设备的请求

    中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力。由于中断处理程序会打断其他进程的运行,所以,为了减少对正常进程运行调度的影响,中断处理程序就需要尽可能快地运行。如果中断本身要做的事情不多,那么处理起来也不会有太大问题;但如果中断要处理的事情很多,中断服务程序就有可能要运行很长时间。特别是,中断处理程序在响应中断时,还会临时关闭中断。这就会导致上一次中断处理完成之前,其他中断都不能响应,也就是说中断有可能会丢失。


    一、什么是软中断?

    事实上,为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:

    • 上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。
    • 下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行。

    我举个最常见的网卡接收数据包的例子,让你更好地理解。网卡接收到数据包后,会通过硬件中断的方式,通知内核有新的数据到了。这时,内核就应该调用中断处理程序来响应它。你可以自己先想一下,这种情况下的上半部和下半部分别负责什么工作呢?对上半部来说,既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个软中断信号,通知下半部做进一步的处理。而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。

    所以,这两个阶段你也可以这样理解:

    • 上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
    • 而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行。

    实际上,上半部会打断 CPU 正在执行的任务,然后立即执行中断处理程序。而下半部以内核线程的方式执行,并且每个 CPU 都对应一个软中断内核线程,名字为 “ksoftirqd/CPU 编号”,比如说, 0 号 CPU 对应的软中断内核线程的名字就是 ksoftirqd/0。

    不过要注意的是,软中断不只包括了刚刚所讲的硬件设备中断处理程序的下半部,一些内核自定义的事件也属于软中断,比如内核调度和 RCU 锁(Read-Copy Update 的缩写,RCU 是 Linux 内核中最常用的锁之一)等。

    二、查看软中断和内核线程

    不知道你还记不记得,前面提到过的 proc 文件系统。它是一种内核空间和用户空间进行通信的机制,可以用来查看内核的数据结构,或者用来动态修改内核的配置。其中:

    • /proc/softirqs 提供了软中断的运行情况;
    • /proc/interrupts 提供了硬中断的运行情况。

    运行下面的命令,查看 /proc/softirqs 文件的内容,你就可以看到各种类型软中断在不同 CPU 上的累积运行次数:

    
    $ cat /proc/softirqs
                        CPU0       CPU1
              HI:          0          0
           TIMER:     811613    1972736
          NET_TX:         49          7		#NET_TX 表示网络发送中断
          NET_RX:    1136736    1506885     #NET_RX 表示网络接收中断
           BLOCK:          0          0
        IRQ_POLL:          0          0
         TASKLET:     304787       3691
           SCHED:     689718    1897539
         HRTIMER:          0          0
             RCU:    1330771    1354737
    

    在查看 /proc/softirqs 文件内容时,你要特别注意以下这两点。

    • 第一,要注意软中断的类型,也就是这个界面中第一列的内容。从第一列你可以看到,软中断包括了 10 个类别,分别对应不同的工作类型。比如NET_RX 表示网络接收中断,NET_TX 表示网络发送中断。
    • 第二,要注意同一种软中断在不同 CPU 上的分布情况,也就是同一行的内容。正常情况下,同一种中断在不同 CPU上的累积次数应该差不多。比如这个界面中,NET_RX 在 CPU0 和 CPU1 上的中断次数基本是同一个数量级,相差不大。

    不过你可能发现,TASKLET 在不同 CPU 上的分布并不均匀。TASKLET 是最常用的软中断实现机制,每个 TASKLET 只运行一次就会结束 ,并且只在调用它的函数所在的 CPU 上运行

    因此,使用 TASKLET 特别简便,当然也会存在一些问题,比如说由于只在一个 CPU 上运行导致的调度不均衡,再比如因为不能在多个 CPU 上并行运行带来了性能限制。另外,刚刚提到过,软中断实际上是以内核线程的方式运行的,每个 CPU 都对应一个软中断内核线程,这个软中断内核线程就叫做 ksoftirqd/CPU 编号。那要怎么查看这些线程的运行状况呢?其实用 ps 命令就可以做到,比如执行下面的指令:

    $ ps aux | grep softirq
    root         7  0.0  0.0      0     0 ?        S    Oct10   0:01 [ksoftirqd/0]
    root        16  0.0  0.0      0     0 ?        S    Oct10   0:01 [ksoftirqd/1]
    

    注意,这些线程的名字外面都有中括号,这说明 ps 无法获取它们的命令行参数(cmline)。一般来说,ps 的输出中,名字括在中括号里的,一般都是内核线程。

    总结

    Linux 中的中断处理程序分为上半部和下半部:

    • 上半部对应硬件中断,用来快速处理中断。
    • 下半部对应软中断,用来异步处理上半部未完成的工作。

    Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,可以通过查看 /proc/softirqs 来观察软中断的运行情况。

    展开全文
  • Linux软中断原理浅析

    2021-05-17 22:36:01
    Linux软中断原理浅析Linux软中断原理浅析Linux中的软中断机制用于中对时间要求最严格以及最重要的中断下半部进行使用。在系统设计过 程中,大家都清楚中断上下文不能处理太多的事情,需要快速的返回,否则很容易导致...

    Linux软中断原理浅析

    Linux软中断原理浅析

    Linux中的软中断机制用于中对时间要求最严格以及最重要的中断下半部进行使用。在系统设计过 程中,大家都清楚中断上下文不能处理太多的事情,需要快速的返回,否则很容易导致中断事件的丢失,所以这就产生了一个问题:中断发生之后的事务处理由谁来 完成?在前后台程序中,由于只有中断上下文和一个任务上下文,所以中断上下文触发事件,设置标记位,任务上下文循环扫描标记位,执行相应的动作,也就是中 断发生之后的事情由任务来完成了,只不过任务上下文采用扫描的方式,实时性不能得到保 证。在系统和Windows系统中,这个不断循环的任务就是本文所要讲述的软中断daemon。在Windows中处理耗时的中断事务称之为中 断延迟处理,在Linux中称之为中断下半部,显然中断上半部处理清中断之类十分清闲的动作,然后在退出中断服务程序时触发中断下半部,完成具体的功能。

    在Linux中,中断下半部的实现基于软中断机制。所以理清楚软中断机制的原理,那么中断下半部的实现也就非常简单了。通过上述的描述,大家也应该 清楚为什么要定义软中断机制了,一句话就是为了要处理对时间要求苛刻的任务,恰好中断下半部就有这样的需求,所以其实现采用了软中断机制。

    构成软中断机制的核心元素包括:

    1、  软中断状态寄存器soft interrupt state(irq_stat)

    2、  软中断向量表(softirq_vec)

    3、  软中断守护daemon

    软中断的工作工程模拟了实际的中断处理过程,当某一软中断时间发生后,首先需要设置对应的中断标记位,触发中断事务,然后唤醒守护线程去检测中断状 态寄存器,如果通过查询发现某一软中断事务发生之后,那么通过软中断向量表调用软中断服务程序action()。这就是软中断的过程,与硬件中断唯一不同 的地方是从中断标记到中断服务程序的映射过程。在CPU的硬件中断发生之后,CPU需要将硬件中断请求通过向量表映射成具体的服务程序,这个过程是硬件自 动完成的,但是软中断不是,其需要守护线程去实现这一过程,这也就是软件模拟的中断,故称之为软中断。

    一个软中断不会去抢占另一个软中断,只有硬件中断才可以抢占软中断,所以软中断能够保证对时间的严格要求。

    Linux中软中断实现分析

    在Linux中最多可以注册32个软中断,目前系统用了6个软中断,他们为:定时器处理、SCSI处理、网络收发处理以及Tasklet机制,这里的tasklet机制就是用来实现下半部的,

    描述软中断的核心数据结构为中断向量表,其定义如下:

    struct softirq_action

    {

    void (*action)(struct softirq_action *); /* 软中断服务程序 */

    void *data;                                         /* 服务程序输入参数 */

    };

    软中断守护daemon是软中断机制的实现核心,其实现过程也比较简单,通过查询软中断状态irq_stat来判断事件是否发生,如果发生,那么映 射到软中断向量表,调用执行注册的action函数就可以了。从这一点分析可以看出,软中断的服务程序的执行上下文为软中断daemon。在Linux中 软中断daemon线程函数为do_softirq()。

    触发软中断事务通过raise_softirq()来实现,该函数就是在中断关闭的情况下设置软中断状态位,然后判断如果不在中断上下文,那么直接唤醒守护daemon。

    常用的软中断函数列表如下:

    1、  Open_softirq,注册一个软中断,将软中断服务程序注册到软中断向量表。2、  Raise_softirq,设置软中断状态bitmap,触发软中断事务。

    Tasklet机制实现分析

    Tasklet为一个软中断,考虑到优先级问题,分别占用了向量表中的0号和5号软中断。

    当tasklet的软中断事件发生之后,执行tasklet-action的软中断服务程序,该服务程序会扫描一个tasklet的任务列表,执行该任务中的具体服务程序。在这里举一个例子加以说明:

    当用户读写USB设备之后,发生了硬件中断,硬件中断服务程序会构建一个tasklet_struct,在该结构中指明了完成该中断任务的具体方法 函数(下半部执行函数),然后将tasklet_struct挂入tasklet的tasklet_struct链表中,这一步可以通过 tasklet_schedule函数完成。最后硬件中断服务程序退出并且CPU开始调度软中断daemon,软中断daemon会发现tasklet发 生了事件,其会执行tasklet-action,然后tasklet-action会扫描tasklet_struct链表,执行具体的USB中断服务 程序下半部。这就是应用tasklet完成中断下半部实现的整个过程。

    Linux中的tasklet实现比较简单,其又封装了一个重要数据结构tasklet_struct,使用tasklet主要函数列表如下:

    1、  tasklet_init,初始化一个tasklet_struct,当然可以采用静态初始化的方法,宏为:DECLARE_TASKLET。

    2、  tasklet_schedule,调度一个tasklet,将输入的tasklet_struct添加到tasklet的链表中。

    Linux中的软中断机制就是模拟了硬件中断的过程,其设计思想完全可以在其他嵌入式OS中得以应用。

    展开全文
  • 第二个配送员也到了,也想给你打电话 第一,要注意软中断的类型,也就是这个界面中第一列的内容 第二,要注意同一种软中断在不同 CPU 上的分布情况,也就是同一行的
  • Linux 软中断机制分析

    万次阅读 多人点赞 2018-09-12 11:57:37
    软中断分析  最近工作繁忙,没有时间总结内核相关的一些东西。上次更新博客到了linux内核中断子系统。这次总结一下软中断,也就是softirq。之后还会总结一些tasklet、工作队列机制。 1. 为什么要软中断  编写...

    软中断分析

        最近工作繁忙,没有时间总结内核相关的一些东西。上次更新博客到了linux内核中断子系统。这次总结一下软中断,也就是softirq。之后还会总结一些tasklet、工作队列机制。

    1. 为什么要软中断

        编写驱动的时候,一个中断产生之后,内核在中断处理函数中可能需要完成很多工作。但是中断处理函数的处理是关闭了中断的。也就是说在响应中断时,系统不能再次响应外部的其它中断。这样的后果会造成有可能丢失外部中断。于是,linux内核设计出了一种架构,中断函数需要处理的任务分为两部分,一部分在中断处理函数中执行,这时系统关闭中断。另外一部分在软件中断中执行,这个时候开启中断,系统可以响应外部中断。

        关于软件中断的理论各种书籍都有介绍,不多叙述。而要真正体会软件中断的作用就必须从代码的角度来分析。我们做工作时候讲求的是professional,当一个人在某个领域一无所知的时候,我们称他为小白,偶,非苹果电脑。小白的脑子里充满了各种问题。慢慢的当这些疑惑解释完之后,小白就脱白了。此时,我们对这个领域的基本框架有了解,但这和professional还有一定的差距。再加以时日,逐渐融会贯通该领域才能达到专业的境界。

    2. 什么时候触发处理软件中断

        说了这么多废话,赶快步入正题。初识软中断,脑子里肯定有不少的疑问,首先就是软件中断在什么地方被触发处理?这个问题的答案就是:一个硬件中断处理完成之后。下面的函数在处理完硬件中断之后推出中断处理函数,在irq_exit中会触发软件中断的处理。

    
    asmlinkage void __exception asm_do_IRQ(unsigned int irq, structpt_regs *regs) 
    { 
        struct pt_regs *old_regs = set_irq_regs(regs); 
      
        irq_enter(); 
      
        /* 
         * Some hardware gives randomly wrong interrupts.  Rather 
         * than crashing, do something sensible. 
         */  
        if (irq >= NR_IRQS) 
            handle_bad_irq(irq, &bad_irq_desc); 
        else  
            generic_handle_irq(irq); 
      
        /* AT91 specific workaround */  
        irq_finish(irq); 
      
        irq_exit(); 
        set_irq_regs(old_regs); 
    }

        这里要注意,invoke_softirq必须满足两个条件才能被调用到,一个就是不是在硬件中断处理过程中或者在软件中断处理中,第二个就是必须有软件中断处于pending状态。第二个好理解,有软件中断产生才去处理,没有就不处理。第一个就不好理解了。

    /* 
    * Exit an interrupt context. Process softirqs if needed and possible:
    */  
    void irq_exit(void) 
    { 
        account_system_vtime(current); 
        trace_hardirq_exit(); 
        sub_preempt_count(IRQ_EXIT_OFFSET); 
        if (!in_interrupt() && local_softirq_pending()) 
            invoke_softirq(); 
      
    #ifdef CONFIG_NO_HZ 
        /* Make sure that timer wheel updates are propagated */  
        rcu_irq_exit(); 
        if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched()) 
            tick_nohz_stop_sched_tick(0); 
    #endif  
        preempt_enable_no_resched(); 
    }

    在linux系统的进程数据结构里,有这么一个数据结构

    #define preempt_count() (current_thread_info()->preempt_count),

    利用preempt_count可以表示是否处于中断处理或者软件中断处理过程中。

    
    #define PREEMPT_MASK    (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) 
    #define SOFTIRQ_MASK    (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) 
    #define HARDIRQ_MASK    (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) 
      
    #define PREEMPT_OFFSET    (1UL << PREEMPT_SHIFT) 
    #define SOFTIRQ_OFFSET    (1UL << SOFTIRQ_SHIFT) 
    #define HARDIRQ_OFFSET    (1UL << HARDIRQ_SHIFT)

    sub_preempt_count(IRQ_EXIT_OFFSET);

    #define in_interrupt() (irq_count())

    #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))

                         wps_clip_image-31524 

        preempt_count的8~23位记录中断处理和软件中断处理过程的计数。如果有计数,表示系统在硬件中断或者软件中断处理过程中。系统这么设计是为了避免软件中断在中断嵌套中被调用,并且达到在单个CPU上软件中断不能被重入的目的。对于ARM架构的CPU不存在中断嵌套中调用软件中断的问题,因为ARM架构的CPU在处理硬件中断的过程中是关闭掉中断的。只有在进入了软中断处理过程中之后才会开启硬件中断,如果在软件中断处理过程中有硬件中断嵌套,也不会再次调用软中断,because硬件中断是软件中断处理过程中再次进入的,此时preempt_count已经记录了软件中断!对于其它架构的CPU,有可能在触发调用软件中断前,也就是还在处理硬件中断的时候,就已经开启了硬件中断,可能会发生中断嵌套,在中断嵌套中是不允许调用软件中断处理的。Why?我的理解是,在发生中断嵌套的时候,表明这个时候是系统突发繁忙的时候,内核第一要务就是赶紧把中断中的事情处理完成,退出中断嵌套。避免多次嵌套,哪里有时间处理软件中断,所以把软件中断推迟到了所有中断处理完成的时候才能触发软件中断。

    3. 软件中断的处理过程

        之前我已经说到,软中断的一个很大的目的就是避免中断处理中,处理的操作过多而丢失中断。同时中断还需要考虑到一件事情就是中断处理过程过长就会影响系统响应时间。如果一个中断处理一秒钟,那你一定能感受到串口卡住的现象。从另外一方面说呢,我们又必须考虑中断处理的操作一定的优先度,毕竟是硬件触发的事务,关系到网络、块设备的效率问题。Linux内核就中断方面就必须考虑平衡这三个方面的问题。而下面我要分析的__do_softirq函数就恰似在这三者之间打太极,游刃有余,面面俱到!

     /* 
    * We restart softirq processing MAX_SOFTIRQ_RESTART times, 
    * and we fall back to softirqd after that. 
    * 
    * This number has been established via experimentation. 
    * The two things to balance is latency against fairness - 
    * we want to handle softirqs as soon as possible, but they 
    * should not be able to lock up the box. 
    */  
    #define MAX_SOFTIRQ_RESTART 10  
      
    asmlinkage void __do_softirq(void) 
    { 
        struct softirq_action *h; 
        __u32 pending; 
        int max_restart = MAX_SOFTIRQ_RESTART; 
        int cpu; 
      
        pending = local_softirq_pending(); 
        account_system_vtime(current); 
      
        __local_bh_disable((unsigned long)__builtin_return_address(0)); 
        trace_softirq_enter(); 
      
        cpu = smp_processor_id(); 
    restart: 
        /* Reset the pending bitmask before enabling irqs */  
        set_softirq_pending(0); 
      
        local_irq_enable(); 
      
        h = softirq_vec; 
      
        do  
        { 
            if (pending & 1) 
            { 
                int prev_count = preempt_count(); 
      
                h->action(h); 
      
                if (unlikely(prev_count != preempt_count())) 
                { 
                    printk(KERN_ERR "huh, entered softirq %td %p"  
                           "with preempt_count %08x,"  
                           " exited with %08x?\n", h - softirq_vec, 
                           h->action, prev_count, preempt_count()); 
                    preempt_count() = prev_count; 
                } 
      
                rcu_bh_qsctr_inc(cpu); 
            } 
            h++; 
            pending >>= 1; 
        } 
        while (pending); 
      
        local_irq_disable(); 
      
        pending = local_softirq_pending(); 
        if (pending && --max_restart) 
            goto restart; 
      
        if (pending) 
            wakeup_softirqd(); 
      
        trace_softirq_exit(); 
      
        account_system_vtime(current); 
        _local_bh_enable(); 
    }
    
    

     __do_softirq函数处理软件中断过程如下图流程分析

    4. 首先调用local_softirq_pending函数取得目前有哪些位存在软件中断

    5. 调用__local_bh_disable关闭软中断,其实就是设置正在处理软件中断标记,在同一个CPU上使得不能重入__do_softirq函数

    6. 重新设置软中断标记为0,set_softirq_pending重新设置软中断标记为0,这样在之后重新开启中断之后硬件中断中又可以设置软件中断位。

    7. 开启硬件中断

    8. 之后在一个循环中,遍历pending标志的每一位,如果这一位设置就会调用软件中断的处理函数。在这个过程中硬件中断是开启的,随时可以打断软件中断。这样保证硬件中断不会丢失。

    9. 之后关闭硬件中断,查看是否又有软件中断处于pending状态,如果是,并且在本次调用__do_softirq函数过程中没有累计重复进入软件中断处理的次数超过10次,就可以重新调用软件中断处理。如果超过了10次,就调用wakeup_softirqd();唤醒内核的一个进程来处理软件中断。设立10次的限制,也是为了避免影响系统响应时间。

                                                   wps_clip_image-25966

    4. 处理软中断内核线程

        之前我说到不能让CPU长时间来处理中断事务,这样会影响系统的响应时间,严重影响用户和系统之间的交互式体验。所以在之前的__do_softirq中最多将循环执行10次,那么当执行了10次仍然有软中断在pending状态,这个时候应该怎么处理呢?系统将唤醒一个软件中断处理的内核进程,在内核进程中处理pending中的软件中断。这里要注意,之前我们分析的触发软件中断的位置其实是中断上下文中,而在软中断的内核线程中实际已经是进程的上下文。

    这里说的软中断上下文指的就是系统为每个CPU建立的ksoftirqd进程。

     

        看完这个函数,我不得不佩服这个函数设计的精巧!而我更多的从中体会到其中蕴藏的一种做人的道理。那就是做人要霸道一点,太谦和太恭维不行,但是又不能横行霸道,原则的问题要公平讲理,一定的时候顾及别人的利益,好处不能一个人独吞。这就跟下面ksoftirqd处理过程一样,该狠的时候禁止抢占,其它进程别想调度到哦,但是自己占用CPU时间过长的话,也自觉的问一问是不是该释放CPU给其它进程了。

        下面我们就来分析一下这个处理过程怎么就体现了上面的这种说法呢?软中断的内核进程中主要有两个大循环,外层的循环处理有软件中断就处理,没有软件中断就休眠。内层的循环处理软件中断,并每循环一次都试探一次是否过长时间占据了CPU,需要调度释放CPU给其它进程。具体的操作在注释中做了解释。

    
    static int ksoftirqd(void *__bind_cpu) 
    { 
        set_current_state(TASK_INTERRUPTIBLE); 
      
        while (!kthread_should_stop()) 
        { 
            /*不管三七二十一首先禁止抢占,我掌握CPU,并全凭我自己掌握调度*/  
            preempt_disable(); 
            if (!local_softirq_pending()) 
            { 
                preempt_enable_no_resched(); 
                /*如果没有软中断在pending,那就让出CPU来吧*/  
                schedule(); 
               /*我被唤醒了,首先掌握CPU,不让自己被抢占,自己决定自己的是否要调度*/  
                preempt_disable(); 
            } 
      
            __set_current_state(TASK_RUNNING); 
      
            while (local_softirq_pending()) 
            { 
                /* Preempt disable stops cpu going offline. 
                   If already offline, we'll be on wrong CPU: 
                   don't process */  
                if (cpu_is_offline((long)__bind_cpu)) 
                    goto wait_to_die; 
                /*处理软中断*/  
                do_softirq(); 
                /*虽然我自己掌握是否要调度,虽然我可以一直不调度,但是我是 
                个正直的人,运行一段时间后我会看看是否需要调度,还其它进程运行*/  
                preempt_enable_no_resched(); 
                cond_resched(); 
                preempt_disable(); 
                rcu_qsctr_inc((long)__bind_cpu); 
            } 
            preempt_enable(); 
            set_current_state(TASK_INTERRUPTIBLE); 
        } 
        __set_current_state(TASK_RUNNING); 
        return 0; 
      
    wait_to_die: 
        preempt_enable(); 
        /* Wait for kthread_stop */  
        set_current_state(TASK_INTERRUPTIBLE); 
        while (!kthread_should_stop()) 
        { 
            schedule(); 
            set_current_state(TASK_INTERRUPTIBLE); 
        } 
        __set_current_state(TASK_RUNNING); 
        return 0; 
    } 
    

     

    文章内容转载自:http://blog.chinaunix.net/uid-28236237-id-3450751.html

     

     

    展开全文
  • 一种基于linux软中断机制的计费网关系统.pdf
  • linux 软中断过高处理

    千次阅读 2019-04-19 15:39:49
    遇到linux中处理集中在一个core上导致单一cpu使用率过高。 出现问题:在压力测试redis集群的时候使用redis-benchmark向集群代理打流。发现代理cpu使用率上升到一定程度就不再上升,而另一cpu ksoftirqd/21 的...
  • arm的软中断是arm从用户模式切换到特权模式,也就是linux中从用户态切换到内核态的过程。 swi命令触发软中断 linux系统中,swi异常向量代码: linux系统调用 x86 架构是硬中断int 80,中断号为80来实现系统调用的; ...
  • linux中断管理—软中断 一、简介 ​ 软中断linux预留给系统中对时间要求最为严苛和最重要的中断下半部使用的。并且,驱动中只有一些对时间极其敏感的模块使用了。例如:块设备和网络子系统。linux系统中定义了几种...
  • linux软中断

    2012-02-07 17:17:01
    详细描述了LINUX软中断机制,对linux开发的人员建议进行阅读。
  • Linux软中断

    2021-10-03 10:02:20
    中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力。 由于中断处理程序会打断其他进程的运行,所以,为了减少对正常进程运行...软中断 为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过
  • 实验六Linux进程间通信24课时 实验目的 理解进程通信原理掌握进程中信号量共享内存消息队列相关的函数的使用 实验原理 Linux下进程通信相关函数除上次实验所用的几个还有 信号量 信号量又称为信号灯它是用来协调不同...
  • 理解Linux软中断

    千次阅读 2019-02-05 14:37:54
    Linux中断是操作系统的自我保护机制,可以保证硬件的交互过程不被意外打断,所以短时间内的中断是正常的。   2:为什么要有中断 中断其实是一种异步的事件处理机制,可以提高系统的并发能力。 比如你订了一份...
  • Linux中断处理过程分成了两个阶段,也就是上半部和下半部: 上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。下半部用来延迟处理上半部未完成的工作,通常以内核...
  • linux软中断源码

    2008-11-20 16:43:15
    linux软中断,软中断是linux系统原“底半处理”的升级,在原有的基础上发展的新的处理方式,以适应多cpu 、多线程的软中断处理。
  • 因此期望让中断处理程序运行得快,并想让它完成的工作量多,这两个目标相互制约,诞生——顶/底半部机制,本文主要介绍中断机制底半部的软中断的详细执行过程。 如需了解中断的整体过程请点击链接:****Linux中断...
  • 使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上发出的中断信号(即按delete键),当父进程接收到这两个软中断的某一个后,父进程用系统调用kill()向两个子进程分别发出整数值为16和17...
  • 1. 怎么去理解 前面博客简单说过中断的含义,中断是系统...由于中断处理程序会打断进程的运行,特别是还会临时关闭中断,会导致上一次中断处理程序完成以前,其他中断都不能响应,那么这种情况下中断也可能会丢失,...
  • 1. 为什么要软中断 编写驱动的时候,一个中断产生之后,内核在中断处理函数中可能需要完成很多工作。但是中断处理函数的处理是关闭了中断的。也就是说在响应中断时,系统不能再次响应外部的其它中断。这样的后果会...
  • Linux内核笔记--软中断

    2020-12-30 21:16:44
    Linux软中断1、软中断介绍2、软中断的使用2.1、注册软中断处理函数2.2、触发软中断 1、软中断介绍 Linux 内核使用结构体 softirq_action 表示软中断, softirq_action结构体定义在文件include/linux/interrupt.h 中...
  • 用一个不可中断进程的案例,带你学习了 iowait(也就是等待 I/O 的 CPU 使用率)升高时的分析方法。这里你要记住,进程的不可中断状态是系统的一种保护机制,可以保证硬件的交互过程不被意外打断。所以,短时间的不...
  • 异步事件驱动方式来提升系统效率,首先会在驱动程序中嵌入中断程序,一旦磁盘准备就绪就会通过驱动程序发生一个中断请求操作,CPU立马停下手里的活来执行中断程序,该中断程序会从磁盘中读取数据到内存中。...
  • 除了iowait,软中断(softirq)CPU使用率升高也是最常见的一种性能问题 一、从取外卖看中断 1.1 中断的定义 中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序...
  • Linux中软中断实现分析在Linux中最多可以注册32个软中断,目前系统用了6个软中断,他们为:定时器处理、SCSI处理、网络收发处理以及Tasklet机制,这里的tasklet机制就是用来实现下半部的,描述软中断的核心数据结构...
  • Linux 中的软中断包括网络收发、定时、调度、RCU锁等各种类型,我们可以查看proc 文件系统中的/proc/softirqs,观察软中断的运行情况。 在Linux中,每个CPU都对应一个软中断内核线程,名字是 ksofirqd/CPU编号。当...
  • Linux进程的软中断通信(signal和kill)

    千次阅读 多人点赞 2020-11-14 22:48:04
    Linux的进程软中断通信一、软中断信号二、函数介绍(1)wait函数(2)signal函数(3)sleep函数(4)kill函数三、示例 一、软中断信号 软中断信号(signalsignalsignal,又简称为信号)用来通知进程发生了事件。进程...
  • linux软中断的实现

    2012-06-11 11:11:27
    linux软中断的实现 中断服务程序往往都是在CPU关中断的条件下执行的,以避免中断嵌套而使控制复杂化。但是CPU关中断的时间不能太长,否则容易丢失中断信号。为此, Linux将中断服务程序一分为二,各称作“Top ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 60,834
精华内容 24,333
关键字:

linux软中断