资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 系统运维 > 运维 > Linux

Linux中断和任务调度

Linux 更新时间: 发布时间: 计算机考试归档 最新发布

Linux中断和任务调度

Q: linux支持中断嵌套吗?

A:以前支持,现在不支持。当ARM处理器收到中断的时候,它进入中断模式,同时ARM处理器的CPSR寄存器的IRQ位会被硬件设置为屏蔽IRQ。

原因是可能会出现同一时间大量中断,如果嵌套可能会造成stack溢出等危险。

裸机流程:
①、使能中断,初始化相应的寄存器。
②、注册中断服务函数,也就是向 irqTable 数组的指定标号处写入中断服务函数
②、中断发生以后进入 IRQ 中断服务函数,在 IRQ 中断服务函数在数组 irqTable 里面查找
具体的中断处理函数,找到以后执行相应的中断处理函数。
新的中断机制,顶底半部。
我们在使用 request_irq 申请中断的时候注册的中断服务函数属于中断处理的上半部,只要中断触发,那么
中断处理函数就会执行。而下半部则负责处理比较费时的,对时间要求不敏感的任务。

        Linux 内核将中断分为上半部和下半部的主要目的就是实现中断处理函数的快进快 出,那些对时间敏感、执行速度快的操作可以放到中断处理函数中,也就是上半部。剩下的所 有工作都可以放到下半部去执行,比如在上半部将数据拷贝到内存中。

而下半部处理分为三种: 1、软中断

softirq_vec我把它叫做软中断动作响应向量表>_<,记录的相应action的种类

struct softirq_action
 {
    void (*action)(struct softirq_action *);
 };
static struct softirq_action softirq_vec[NR_SOFTIRQS];

enum
{
 HI_SOFTIRQ=0, 
 TIMER_SOFTIRQ, 
 NET_TX_SOFTIRQ, 
 NET_RX_SOFTIRQ, 
 BLOCK_SOFTIRQ, 
 BLOCK_IOPOLL_SOFTIRQ, 
 TASKLET_SOFTIRQ, 
 SCHED_SOFTIRQ, 
 HRTIMER_SOFTIRQ, 
 RCU_SOFTIRQ, 
 NR_SOFTIRQS
};
NR_SOFTIRQS = 10;

软中断必须在编译的时候静态注册,上半部可以打断软中断,有数量限值最大32个,过多会影响内核效率,因为其是轮询处理。

2、tasklet

tasklet是通过软中断实现的,所以它本身也是软中断。Tasklet采用无差别的队列机制。

    (1)无类型数量限制;

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

  (3)支持SMP机制;

    它的特性如下:

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

  2)多个不同类型的tasklet可以并行在多个CPU上。
 struct tasklet_struct
{
    struct tasklet_struct *next; 
    unsigned long state; 
    atomic_t count; 
    void (*func)(unsigned long); 
    unsigned long data; 
};
void tasklet_init(struct tasklet_struct *t,
                    void (*func)(unsigned long), unsigned long data);

函数参数和返回值含义如下:
t:要初始化的 tasklet
func:tasklet 的处理函数。
data:要传递给 func 函数的参数

void tasklet_schedule(struct tasklet_struct *t)

下半部相应*func参数同样为(unsigned long),可以放自定义的设备指针值。

3,工作队列

        可打断,可阻塞。上面两个运行与中断上下文,不可阻塞,而工作队列则是内核的一个线程。

关于Linux中断  

        多个中断可以放在一个线程中,也可以每个中断分配一个线程。我们用结构体workqueue_struct表示工作者线程,工作者线程是用内核线程实现的。

        而工作者线程是如何执行被推后的工作——有这样一个链表,它由结构体work_struct组成,而这个work_struct则描述了一个工作,一旦这个工作被执行完,相应的work_struct对象就从链表上移去,当链表上不再有对象时,工作者线程就会继续休眠。

struct work_struct {
 atomic_long_t data; 
 struct list_head entry;
 work_func_t func; 
};

struct workqueue_struct { 
    struct list_head pwqs; 
    struct list_head list; 
    ...
    struct worker *rescuer; 
    ...
}

struct worker {
     union {
         struct list_head entry; 
         struct hlist_node hentry;
     };
     struct work_struct *current_work; 
     work_func_t current_func; 
     struct pool_workqueue *current_pwq;
     ...
     ...
     struct workqueue_struct *rescue_wq;
};

使用起来bool schedule_work(struct work_struct *work)更温和,可阻塞,对时间更不敏感。

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/344486.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【Linux中断和任务调度】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2