硬中断和软中断

2023-10-30

本文主要内容:硬中断 / 软中断的原理和实现

内核版本:2.6.37

Author:zhangskd @ csdn blog

 

概述

 

从本质上来讲,中断是一种电信号,当设备有某种事件发生时,它就会产生中断,通过总线把电信号发送给中断控制器。

如果中断的线是激活的,中断控制器就把电信号发送给处理器的某个特定引脚。处理器于是立即停止自己正在做的事,

跳到中断处理程序的入口点,进行中断处理。

 

(1) 硬中断

由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包

的时候,就会发出一个中断。我们通常所说的中断指的是硬中断(hardirq)。

 

(2) 软中断

为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间

就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。

 

(3) 中断嵌套

Linux下硬中断是可以嵌套的,但是没有优先级的概念,也就是说任何一个新的中断都可以打断正在执行的中断,但同种中断

除外。软中断不能嵌套,但相同类型的软中断可以在不同CPU上并行执行。

 

(4) 软中断指令

int是软中断指令。

中断向量表是中断号和中断处理函数地址的对应表。

int n - 触发软中断n。相应的中断处理函数的地址为:中断向量表地址 + 4 * n。

 

(5)硬中断和软中断的区别

软中断是执行中断指令产生的,而硬中断是由外设引发的。

硬中断的中断号是由中断控制器提供的,软中断的中断号由指令直接指出,无需使用中断控制器。

硬中断是可屏蔽的,软中断不可屏蔽。

硬中断处理程序要确保它能快速地完成任务,这样程序执行时才不会等待较长时间,称为上半部。

软中断处理硬中断未完成的工作,是一种推后执行的机制,属于下半部。 

 

开关

 

(1) 硬中断的开关

简单禁止和激活当前处理器上的本地中断:

local_irq_disable();

local_irq_enable();

保存本地中断系统状态下的禁止和激活:

unsigned long flags;

local_irq_save(flags);

local_irq_restore(flags);

 

(2) 软中断的开关

禁止下半部,如softirq、tasklet和workqueue等:

local_bh_disable();

local_bh_enable();

需要注意的是,禁止下半部时仍然可以被硬中断抢占。

 

(3) 判断中断状态

#define in_interrupt() (irq_count()) // 是否处于中断状态(硬中断或软中断)

#define in_irq() (hardirq_count()) // 是否处于硬中断

#define in_softirq() (softirq_count()) // 是否处于软中断

 

硬中断

 

(1) 注册中断处理函数

注册中断处理函数:

/**
 * irq: 要分配的中断号
 * handler: 要注册的中断处理函数
 * flags: 标志(一般为0)
 * name: 设备名(dev->name)
 * dev: 设备(struct net_device *dev),作为中断处理函数的参数
 * 成功返回0
 */

int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, 
    const char *name, void *dev);

 

中断处理函数本身:

typedef irqreturn_t (*irq_handler_t) (int, void *);

/**
 * enum irqreturn
 * @IRQ_NONE: interrupt was not from this device
 * @IRQ_HANDLED: interrupt was handled by this device
 * @IRQ_WAKE_THREAD: handler requests to wake the handler thread
 */
enum irqreturn {
    IRQ_NONE,
    IRQ_HANDLED,
    IRQ_WAKE_THREAD,
};
typedef enum irqreturn irqreturn_t;
#define IRQ_RETVAL(x) ((x) != IRQ_NONE)

 

(2) 注销中断处理函数

/**
 * free_irq - free an interrupt allocated with request_irq
 * @irq: Interrupt line to free
 * @dev_id: Device identity to free
 *
 * Remove an interrupt handler. The handler is removed and if the
 * interrupt line is no longer in use by any driver it is disabled.
 * On a shared IRQ the caller must ensure the interrupt is disabled
 * on the card it drives before calling this function. The function does
 * not return until any executing interrupts for this IRQ have completed.
 * This function must not be called from interrupt context.
 */

void free_irq(unsigned int irq, void *dev_id);

 

软中断

 

(1) 定义

软中断是一组静态定义的下半部接口,可以在所有处理器上同时执行,即使两个类型相同也可以。

但一个软中断不会抢占另一个软中断,唯一可以抢占软中断的是硬中断。

 

软中断由softirq_action结构体表示:

struct softirq_action {
    void (*action) (struct softirq_action *); /* 软中断的处理函数 */
};

 

目前已注册的软中断有10种,定义为一个全局数组:

static struct softirq_action softirq_vec[NR_SOFTIRQS];

enum {
    HI_SOFTIRQ = 0, /* 优先级高的tasklets */
    TIMER_SOFTIRQ, /* 定时器的下半部 */
    NET_TX_SOFTIRQ, /* 发送网络数据包 */
    NET_RX_SOFTIRQ, /* 接收网络数据包 */
    BLOCK_SOFTIRQ, /* BLOCK装置 */
    BLOCK_IOPOLL_SOFTIRQ,
    TASKLET_SOFTIRQ, /* 正常优先级的tasklets */
    SCHED_SOFTIRQ, /* 调度程序 */
    HRTIMER_SOFTIRQ, /* 高分辨率定时器 */
    RCU_SOFTIRQ, /* RCU锁定 */
    NR_SOFTIRQS /* 10 */
};

 

(2) 注册软中断处理函数

/**
 * @nr: 软中断的索引号
 * @action: 软中断的处理函数
 */

void open_softirq(int nr, void (*action) (struct softirq_action *))
{
    softirq_vec[nr].action = action;
}

例如:

open_softirq(NET_TX_SOFTIRQ, net_tx_action);

open_softirq(NET_RX_SOFTIRQ, net_rx_action);

 

(3) 触发软中断 

调用raise_softirq()来触发软中断。

void raise_softirq(unsigned int nr)
{
    unsigned long flags;
    local_irq_save(flags);
    raise_softirq_irqoff(nr);
    local_irq_restore(flags);
}

/* This function must run with irqs disabled */
inline void rasie_softirq_irqsoff(unsigned int nr)
{
    __raise_softirq_irqoff(nr);

    /* If we're in an interrupt or softirq, we're done
     * (this also catches softirq-disabled code). We will
     * actually run the softirq once we return from the irq
     * or softirq.
     * Otherwise we wake up ksoftirqd to make sure we
     * schedule the softirq soon.
     */
    if (! in_interrupt()) /* 如果不处于硬中断或软中断 */
        wakeup_softirqd(void); /* 唤醒ksoftirqd/n进程 */
}


Percpu变量irq_cpustat_t中的__softirq_pending是等待处理的软中断的位图,通过设置此变量

即可告诉内核该执行哪些软中断。

static inline void __rasie_softirq_irqoff(unsigned int nr)
{
    trace_softirq_raise(nr);
    or_softirq_pending(1UL << nr);
}

typedef struct {
    unsigned int __softirq_pending;
    unsigned int __nmi_count; /* arch dependent */
} irq_cpustat_t;

irq_cpustat_t irq_stat[];
#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
#define or_softirq_pending(x) percpu_or(irq_stat.__softirq_pending, (x))
#define local_softirq_pending() percpu_read(irq_stat.__softirq_pending)

 

唤醒ksoftirqd内核线程处理软中断。

static void wakeup_softirqd(void)
{
    /* Interrupts are disabled: no need to stop preemption */
    struct task_struct *tsk = __get_cpu_var(ksoftirqd);

    if (tsk && tsk->state != TASK_RUNNING)
        wake_up_process(tsk);
}

 

在下列地方,待处理的软中断会被检查和执行:

1. 从一个硬件中断代码处返回时

2. 在ksoftirqd内核线程中

3. 在那些显示检查和执行待处理的软中断的代码中,如网络子系统中

 

而不管是用什么方法唤起,软中断都要在do_softirq()中执行。如果有待处理的软中断,

do_softirq()会循环遍历每一个,调用它们的相应的处理程序。

在中断处理程序中触发软中断是最常见的形式。中断处理程序执行硬件设备的相关操作,

然后触发相应的软中断,最后退出。内核在执行完中断处理程序以后,马上就会调用

do_softirq(),于是软中断开始执行中断处理程序完成剩余的任务。

 

下面来看下do_softirq()的具体实现。

asmlinkage void do_softirq(void)
{
    __u32 pending;
    unsigned long flags;

    /* 如果当前已处于硬中断或软中断中,直接返回 */
    if (in_interrupt()) 
        return;

    local_irq_save(flags);
    pending = local_softirq_pending();
    if (pending) /* 如果有激活的软中断 */
        __do_softirq(); /* 处理函数 */
    local_irq_restore(flags);
}
/* 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.
 */
asmlinkage void __do_softirq(void)
{
    struct softirq_action *h;
    __u32 pending;
    /* 本函数能重复触发执行的次数,防止占用过多的cpu时间 */
    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), SOFTIRQ_OFFSET);
    lockdep_softirq_enter(); /* current->softirq_context++ */
    cpu = smp_processor_id(); /* 当前cpu编号 */

restart:
    /* Reset the pending bitmask before enabling irqs */
    set_softirq_pending(0); /* 重置位图 */
    local_irq_enable();
    h = softirq_vec;
    do {
        if (pending & 1) {
            unsigned int vec_nr = h - softirq_vec; /* 软中断索引 */
            int 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())) {
                printk(KERN_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());
            }
            rcu_bh_qs(cpu);
        }
        h++;
        pending >>= 1;
    } while(pending);

    local_irq_disable();
    pending = local_softirq_pending();
    if (pending & --max_restart) /* 重复触发 */
        goto restart;

    /* 如果重复触发了10次了,接下来唤醒ksoftirqd/n内核线程来处理 */
    if (pending)
        wakeup_softirqd(); 

    lockdep_softirq_exit();
    account_system_vtime(current);
    __local_bh_enable(SOFTIRQ_OFFSET);
}

 

(4) ksoftirqd内核线程

内核不会立即处理重新触发的软中断。

当大量软中断出现的时候,内核会唤醒一组内核线程来处理。

这些线程的优先级最低(nice值为19),这能避免它们跟其它重要的任务抢夺资源。

但它们最终肯定会被执行,所以这个折中的方案能够保证在软中断很多时用户程序不会

因为得不到处理时间而处于饥饿状态,同时也保证过量的软中断最终会得到处理。

 

每个处理器都有一个这样的线程,名字为ksoftirqd/n,n为处理器的编号。

static int run_ksoftirqd(void *__bind_cpu)
{
    set_current_state(TASK_INTERRUPTIBLE);
    current->flags |= PF_KSOFTIRQD; /* I am ksoftirqd */

    while(! kthread_should_stop()) {
        preempt_disable();

        if (! local_softirq_pending()) { /* 如果没有要处理的软中断 */
            preempt_enable_no_resched();
            schedule();
            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))/* 被要求释放cpu */
                 goto wait_to_die;

            do_softirq(); /* 软中断的统一处理函数 */

            preempt_enable_no_resched();
            cond_resched();
            preempt_disable();
            rcu_note_context_switch((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;
}


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

硬中断和软中断 的相关文章

  • Linux 上 UDP 和 TCP 的内核绕过 - 它涉及什么?

    Per http www solacesystems com blog kernel bypass revving up linux networking http www solacesystems com blog kernel byp
  • 为什么使用 __get_free_pages() 进行顺序为 10 或 11 的页面分配通常会失败?

    我的系统内存充足 24GB的服务器 在我的系统中 内核空间分配了320MB和120MB用于崩溃内核 其余的内存用于其他目的 但是 当我使用 get free pages 分配顺序为 11 的连续页 内核无法分配 2 10 页 为什么 根据制
  • 破坏用户空间是什么意思? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这可能是一个简单的问题 但是 我听说在内核上工作的唯一规则是不要破坏 用户空间 所以我想知道这意味着什么 打破用户空间这是怎么发生的 Ed
  • 物理地址、设备地址和虚拟地址的区别

    有什么区别设备地址 实际地址 and 虚拟地址 其实我正在努力mmap在驱动程序中 我一直坚持这个概念 The 文档 https www kernel org doc Documentation DMA API HOWTO txt says
  • 如何从内核空间读取/写入 linux /proc 文件?

    我正在编写一个由用户程序和内核模块组成的程序 内核模块需要收集数据 然后将其 发送 到用户程序 这必须通过 proc 文件来完成 现在 我创建了文件 一切都很好 并且花了很长时间在互联网上寻找答案 但仍然找不到 如何读 写 proc 文件f
  • 如何在Linux内核中启用CONFIG_PREEMPT选项?

    我是 Linux 内核编程的新手 尝试在 x86 64 上使用旧内核 Linux 2 6 32 我想启用其中的 CONFIG PREEMPT 选项 但找不到有关如何执行此操作的信息 我可以使用我的首选选项编译新内核 但不知道在这种情况下我需
  • 操作系统如何知道缺失页面的磁盘地址?

    分页充当虚拟地址空间和物理地址空间之间的间接层 给定一个地址 操作系统 OS 内存管理单元 MMU 将其转换为主内存位置 我的问题是 主内存中不存在该页面的情况 操作系统如何知道在磁盘上哪里可以找到该页面 它在哪里存储1的信息 它不存储在页
  • 从 Linux 内核模块的文件描述符获取文件名/路径?

    在Linux内核模块中 有没有一种方法可以从文件名 路径中获取文件名 路径 unsigned int fd 我知道这个答案 如何从内核模块内的文件描述符获取文件名 https stackoverflow com questions 8250
  • 内核如何区分线程和进程

    Linux 中的线程被称为轻量级进程 无论是进程还是线程 它们的实现都是通过task struct数据结构 1 gt 那么 从这个意义上说 内核如何区分线程和进程 2 gt 当发生上下文切换时 线程如何在上下文切换中获得更少的开销 因为在此
  • Linux 源代码中的哪个位置会识别特定的 USB 设备?

    我有一个特定的 USB 设备 我想检查其 Linux 驱动程序源代码 我的理解是 USB 驱动程序执行的第一步是注册自己能够处理具有特定供应商 ID 和产品 ID 的设备 就我而言 供应商 ID 是0BDA产品 ID 是8187 有了这些信
  • 设置 IRQ 映射

    我正在遵循一些教程和参考文献来尝试设置我的内核 我在教程中遇到了一些不熟悉的代码 但根本没有解释它 这是我被告知映射的代码16 IRQs 0 15 到 ISR 地点32 47 void irq remap void outportb 0x2
  • 内核开发和 C++ [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从我know https stackoverflow com questions 580292 what languages are windo
  • C#驱动开发?

    在我一头扎进 C 之前 我一直认为 C 或 C 最适合在 Windows 上开发驱动程序 我不喜欢在 NET 机器上开发驱动程序的想法 但 NET 似乎是 MS 应用程序开发的方向 所以我现在想知道 人们正在使用 C 来开发驱动程序吗 您是
  • Linux 内核标识符中前导和尾随下划线的含义是什么?

    我不断遇到一些小约定 比如 KERNEL Are the 在这种情况下 是内核开发人员使用的命名约定 还是以这种方式命名宏的语法特定原因 整个代码中有很多这样的例子 例如 某些函数和变量以 甚至 这有什么具体原因吗 它似乎被广泛使用 我只需
  • 使用 strace 修复挂起内存问题

    我有一个在 RHEL6 x 64 位 上运行的多线程进程 我发现当我尝试启动该进程时 该进程挂起并且大多数线程 同一进程的 崩溃 有些线程等待线程之间的共享内存被创建 我可以看到所有的共享内存都没有被创建 但是当我使用 strace 时 进
  • Linux 上的“软/硬 nofile”是什么意思

    当我尝试在RedHat EL5上安装软件时 我得到了错误 软 硬nofile的期望值是4096 而默认值是1024 我设法增加了这个数字 但我不知道参数是什么 他们指的是软链接和硬链接吗 我改变的方法是 a 修改 etc security
  • 使用“kde”函数进行 R 中的 5-D 核密度估计

    我想通过使用 R 的 ks 库中的 kde 函数来执行 5 维数据 x y z 时间 大小 的核密度估计 在它的手册中 它说它可以执行核密度估计1 至 6 维数据 手册第 24 页 http cran r project org web p
  • 如何在用户空间程序中使用内核 libcrc32c (或相同的函数)?

    我想在我自己的用户空间程序中进行一些 CRC 检查 我发现内核加密库已经在系统中 并且支持 SSE4 2 我尝试直接 include
  • vmsplice() 和 TCP

    在原来的vmsplice 执行 有人建议 http lwn net Articles 181169 如果您的用户态缓冲区是管道中可容纳的最大页面数的 2 倍 则缓冲区后半部分成功的 vmsplice 将保证内核使用缓冲区的前半部分完成 但事
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v

随机推荐

  • cookies、sessionStorage和localStorage解释及区别

    转载自此文 cookies sessionStorage和localStorage解释及区别 目录 一 cookie和session 两者区别 1 保持状态 2 使用方式 1 cookie机制 2 session机制 3 存储内容 4 存储
  • 华为研发工程师编程题

    空汽水瓶 某商店规定 三个空汽水瓶可以换一瓶汽水 允许向老板借空汽水瓶 但是必须要归还 小张手上有n个空汽水瓶 她想知道自己最多可以喝到多少瓶汽水 数据范围 输入的正整数满足 注意 本题存在多组输入 输入的 0 表示输入结束 并不用输出结果
  • 生成echarts雷达图并传到Server端生成图片

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 需求 使用百度的echarts生成雷达图 并上传到服务器端然后处理 使用各个工具 一 echarts实例及文档 请查看官方地址链接地址 二 html2canvas 代码示例
  • 组合总和(回溯),leetcode习题

    组合总和 找出所有相加之和为 n 的 k 个数的组合 组合中只允许含有 1 9 的正整数 并且每种组合中不存在重复的数字 说明 所有数字都是正整数 解集不能包含重复的组合 示例 1 输入 k 3 n 7 输出 1 2 4 示例 2 输入 k
  • protobuf反射详解及应用(pb/json相互转换)

    关于protobuf的使用 编码原理 编码原理应用 可以分别参见以下文章 Python 操作 protobuf 常见用法 linux环境下protobuf的安装与使用 Protobuf编码规则详解 protobuf编码原理及其在schema
  • SpringCloud(三):Hystrix服务降级与熔断

    前言 上期SpringCloud 二 服务调用和负载均衡通过Eureka注册中心构建一个简单微服务 并通过RestTemplate进行远程调用 当系统中微服务较多 某些微服务会不可避免出现异常 雪崩效应 在微服务架构中 服务与服务之间存在相
  • vue-cli3.0实现播放rtmp直播流

    前言 用vue来实现播放rtmp 代码很简单 主要用的ckplayer 在使用过videojs video等其他插件以后 在播放视频直播流这里 觉得还是ckplayer比较给力 这里说下使用方法 实现效果 目录 实现步骤 一 下载ckpla
  • lecture1 Introduction-笔记

    本文参考了该作者的一些图解和见解 https zhuanlan zhihu com p 128156349 由于疫情原因 偶然间学习了南大的软件分析 Static Analysis 课程 后面会用SA来替代Static Analysis 因
  • JAVA Spring JavaBean 引入 JavaBean ( 外部引用, 内部定义, 级联属性 )

  • AppIconTemplate基本使用教程,快速生成iOS app icon图标

    下面的文章写的挺详细的 我就不过多阐述了 转载 http www zcool com cn article ZNjE1MTI html
  • Selenium自动化工具介绍、安装

    selenium特点 开源软件 跨平台 支持多种浏览器 支持多语言 成熟稳定功能强大 版本 selenium1 0 selenium grid 通过grid可以将脚本下发到不同的电脑不同的浏览器取去执行 selenium rc 由js封装的
  • 吉他谱:Melodies of Life - Final Fantasy Solo Guitar Collections

    原始出处 Final Fantasy Solo Guitar Collections 南泽大介改编的最终幻想9主题曲吉他谱 更多吉他谱 https github com NaisuXu Guitar Sheet Music Collecti
  • HTML基本结构

    一 网页三大组成部分 结构 html 是超文本标记语言 用来搭建网页的结构 样式 css 网页的样式 行为 js 是一种语言 称为脚本语言 交互行为 用户对网页的操作 数据交互 二 HTML语法规范 1 语法 英文状态下输入 html标签
  • C#——委托

    什么是委托 C 中的委托 Delegate 类似于 C 或 C 中函数的指针 委托 Delegate 是存有对某个方法的引用的一种引用类型变量 引用可在运行时被改变 声明委托 委托声明决定了可由该委托引用的方法 委托可指向一个与其具有相同标
  • STM32基础(7)定时器中断

    原理 STM32F1 的定时器非常多 由 2 个基本定时器 TIM6 TIM7 4 个通用定时器 TIM2 TIM5 和 2 个高级定时器 TIM1 TIM8 组成 基本定时器的功能最为简单 类似于 51 单片机内定时器 通用定时器是在基本
  • Unity RenderTexture实现 刮彩票、橡皮擦、擦除效果(3D物体)

    一 实现效果 类似刮刮乐的擦除效果 支持多笔擦除 一次擦不干净 二 所用技术点 RenderTexture Shader 三 实现原理 一个相机单独渲染笔刷轨迹到RenderTexture上 在通过RenderTexture中的笔刷路径修改
  • Ubuntu chrome 浏览器鼠标飘

    问题 ubuntu 系统 4k分辨率下 Chrome 或类似浏览器在全屏模式下 鼠标发飘或卡顿 原因 驱动问题 显卡未得到完全驱动 sudo ubuntu drivers devices sudo ubuntu drivers autoin
  • node升级的正确方法

    注 抱歉之前没有注明该node升级方法为linux环境下的node 现在增加windows下的升级方法 其实对于一些开源的库或者框架个人还是比较建议直接去相应的官网查看会比较好 而且很多都支持中文版 贴上node官网 本文主要是针对安装了n
  • 怎样查看Linux服务器配置

    1 前言 本文主要讲解如何查看Linux服务器配置 主要是查看服务器硬件配置 怎样查看Linux服务器配置 2 查看CPU信息 2 1 使用 lscpu 命令查看服务器CPU信息 lscpu 如下图 使用lscpu命令查看服务器CPU信息
  • 硬中断和软中断

    本文主要内容 硬中断 软中断的原理和实现 内核版本 2 6 37 Author zhangskd csdn blog 概述 从本质上来讲 中断是一种电信号 当设备有某种事件发生时 它就会产生中断 通过总线把电信号发送给中断控制器 如果中断的