当前位置: 首页 > news >正文

linux 内核软中断介绍

在介绍软中断之前,先来介绍一个概念:中断下半部:
为了避免处理复杂的中断嵌套,中断处理程序是在关闭中断的情况下执行的。可是,如果关闭中断的时间太长,可能导致中断请求丢失。例如周期时钟每隔 10 毫秒发送一个中断请求,如果执行某个中断处理程序花费的时间超过 10 毫秒,在这段时间里时钟发送了两个中断请求,但是处理器只认为收到一个时钟中断请求。
最激进的解决办法是中断线程化,但是常用的解决办法是:把中断处理程序分为两部分,上半部(top half, th)在关闭中断的情况下执行,只做对时间非常敏感、与硬件相关或者不能被其他中断打断的工作;下半部(bottom half,bh)在开启中断的情况下执行,可以被其他中断打断。
上半部称为硬中断(hardirq),下半部有 3 种:软中断(softirq)、小任务(tasklet)和工作队列(workqueue)。 3 种下半部的区别如下。
(1)软中断和小任务是工作在中断上下文不允许睡眠;工作队列是使用内核线程实现的是工作在进程上下文,处理函数可以睡眠。
(2)软中断的种类是编译时静态定义的,在运行时不能添加或删除;小任务可以在运行时添加或删除。
(3)同一种软中断的处理函数可以在多个处理器上同时执行,处理函数必须是可以重入的,需要使用锁保护临界区;一个小任务同一时刻只能在一个处理器上执行,不要求处理函数是可以重入的。

软中断(softirq)是中断处理程序在开启中断的情况下执行的部分,可以被硬中断抢占。
内核定义了一张软中断向量表,每种软中断有一个唯一的编号,对应一个 softirq_action实例, softirq_action 实例的成员 action 是处理函数。
kernel/softirq.c
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;

include/linux/interrupt.h
struct softirq_action
{
void (*action)(struct softirq_action *);
};

2.1    软中断的种类
目前内核定义了 10 种软中断,各种软中断的编号如下:
include/linux/interrupt.h
enum
{
    HI_SOFTIRQ=0,
    TIMER_SOFTIRQ,
    NET_TX_SOFTIRQ,
    NET_RX_SOFTIRQ,
    BLOCK_SOFTIRQ,
    IRQ_POLL_SOFTIRQ,
    TASKLET_SOFTIRQ,
    SCHED_SOFTIRQ,
    HRTIMER_SOFTIRQ, /* 没有使用,但是保留,因为有些工具依赖这个编号 */
    RCU_SOFTIRQ, /* RCU软中断应该总是最后一个软中断 */
    
    NR_SOFTIRQS
};
(1) HI_SOFTIRQ:高优先级的小任务。
(2) TIMER_SOFTIRQ:定时器软中断。
(3) NET_TX_SOFTIRQ:网络栈发送报文的软中断。
(4) NET_RX_SOFTIRQ:网络栈接收报文的软中断。
(5) BLOCK_SOFTIRQ:块设备软中断。
(6) IRQ_POLL_SOFTIRQ:支持 I/O 轮询的块设备软中断。
(7) TASKLET_SOFTIRQ:低优先级的小任务。
(8) SCHED_SOFTIRQ:调度软中断,用于在处理器之间负载均衡。
(9) HRTIMER_SOFTIRQ:高精度定时器,这种软中断已经被废弃,目前在中断处理程序的上半部处理高精度定时器。
(10) RCU_SOFTIRQ: RCU 软中断。
软中断的编号形成了优先级顺序,编号小的软中断优先级高。


  注册软中断的处理函数


函数 open_softirq()用来注册软中断的处理函数,在软中断向量表中为指定的软中断编号设置处理函数。
kernel/softirq.c
void open_softirq(int nr, void (*action)(struct softirq_action *))
{
    softirq_vec[nr].action = action;
}

同一种软中断的处理函数可以在多个处理器上同时执行,处理函数必须是可以重入的,需要使用锁保护临界区。


  触发软中断


函数 raise_softirq 用来触发软中断,参数是软中断编号。
void raise_softirq(unsigned int nr);

在已经禁止中断的情况下可以调用函数 raise_softirq_irqoff 来触发软中断。
void raise_softirq_irqoff(unsigned int nr);

函数 raise_softirq 在当前处理器的待处理软中断位图中为指定的软中断编号设置对应的位,如下所示:
raise_softirq() -> raise_softirq_irqoff() -> __raise_softirq_irqoff()
kernel/softirq.c
void __raise_softirq_irqoff(unsigned int nr)
{
    or_softirq_pending(1UL << nr);
}

把宏 or_softirq_pending 展开以后是:
irq_stat[smp_processor_id()].__softirq_pending |= (1UL << nr);


 执行软中断


内核执行软中断的地方如下。
(1)在中断处理程序的后半部分执行软中断,对执行时间有限制:不能超过 2 毫秒,并且最多执行 10 次。
(2)每个处理器有一个软中断线程,调度策略是 SCHED_NORMAL,优先级是 120。
(3)开启软中断的函数 local_bh_enable()。

如果开启了强制中断线程化的配置宏 CONFIG_IRQ_FORCED_THREADING,并且在引导内核的时候指定内核参数“ threadirqs”,那么所有软中断由软中断线程执行。

(1)中断处理程序执行软中断。
在中断处理程序的后半部分,调用函数 irq_exit()以退出中断上下文,处理软中断,其代码如下:
kernel/softirq.c
void irq_exit(void)
{
    …
    preempt_count_sub(HARDIRQ_OFFSET);
    if (!in_interrupt() && local_softirq_pending())
        invoke_softirq();
    …
}
如果 in_interrupt()为真,表示在不可屏蔽中断、硬中断或软中断上下文,或者禁止软中断。
这里我们提一下本地中断的开启与关闭,当中断上来时,为了防止中断的嵌套,硬件会自动关闭本地中断,那本地中断什么时候打开呢?分两种情况:
1.    退出中断上下文时若有待处理的软中断,在执行软中断前__do_softirq->local_irq_enable会打开本地中断,即软中可以被硬件中断的打断。
2.    没有要处理的软中断,那么在中断完全退出时,会恢复被中断进程的寄存器上下文,系统状态寄存器一但被恢复,本地中断自然也就开了。
如果正在处理的硬中断没有抢占正在执行的软中断,没有禁止软中断,并且当前处理器的待处理软中断位图不是空的,那么调用函数 invoke_softirq()来处理软中断。
函数 invoke_softirq 的代码如下:
kernel/softirq.c
1 static inline void invoke_softirq(void)
2 {
3       if (ksoftirqd_running())
4           return;
5       
6       if (!force_irqthreads) {
7           __do_softirq();
8       } else {
9           wakeup_softirqd();
10      }
11 }
第 3 行代码,如果软中断线程处于就绪状态或运行状态,那么让软中断线程执行软中断。
第 6 行和第 7 行代码,如果没有强制中断线程化,那么调用函数__do_softirq()执行软中断。
第 8 行和第 9 行代码,如果强制中断线程化,那么唤醒软中断线程执行软中断。

函数__do_softirq 是执行软中断的核心函数,其主要代码如下:
kernel/softirq.c
1 #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2)
2 #define MAX_SOFTIRQ_RESTART 10
3 asmlinkage __visible void __softirq_entry __do_softirq(void)
4 {
5   unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
6   unsigned long old_flags = current->flags;
7   int max_restart = MAX_SOFTIRQ_RESTART;
8   struct softirq_action *h;
9   bool in_hardirq;
10  __u32 pending;
11  int softirq_bit;
12
13  …
14  pending = local_softirq_pending();
15  …
16  __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
17  …
18
19  restart:
20  set_softirq_pending(0);
21
22  local_irq_enable();
23
24  h = softirq_vec;
25
26  while ((softirq_bit = ffs(pending))) {
27      …
28      h += softirq_bit - 1;
29      …
30      h->action(h);
31      …
32      h++;
33      pending >>= softirq_bit;
34  }
35
36  …
37  local_irq_disable();
38
39  pending = local_softirq_pending();
40  if (pending) {
41      if (time_before(jiffies, end) && !need_resched() &&
42          --max_restart)
43          goto restart;
44
45      wakeup_softirqd();
46  }
47
48  …
49  __local_bh_enable(SOFTIRQ_OFFSET);
50  …
51}

第 14 行代码,把局部变量 pending 设置为当前处理器的待处理软中断位图。
第 16 行代码,把抢占计数器的软中断计数加 1。
第 20 行代码,把当前处理器的待处理软中断位图重新设置为 0。
第 22 行代码,开启硬中断。
第 26~34 行代码,从低位向高位扫描待处理软中断位图,针对每个设置了对应位的软中断编号,执行软中断的处理函数。
第 37 行代码,禁止硬中断。
第 40 行代码,如果软中断的处理函数又触发软中断,处理如下。
a)    第 41~43 行代码,如果软中断的执行时间小于 2 毫秒,不需要重新调度进程,并且软中断的执行次数没超过 10,那么跳转到第 19 行代码继续执行软中断。
b)    第 45 行代码,唤醒软中断线程执行软中断。
第 49 行代码,把抢占计数器的软中断计数减 1。

(2)软中断线程
每个处理器有一个软中断线程,名称是“ ksoftirqd/”后面跟着处理器编号,调度策略是 SCHED_NORMAL,优先级是 120。
软中断线程的核心函数是 run_ksoftirqd(),其代码如下:
kernel/softirq.c
static void run_ksoftirqd(unsigned int cpu)
{
    local_irq_disable();
    if (local_softirq_pending()) {
        __do_softirq();
        local_irq_enable();
        …
        return;
    }
    local_irq_enable();
}

(3)开启软中断时执行软中断。
当进程调用函数 local_bh_enable()开启软中断的时候,如果是开启最外层的软中断,并且当前处理器的待处理软中断位图不是空的,那么执行软中断。
local_bh_enable() -> __local_bh_enable_ip()
kernel/softirq.c
void __local_bh_enable_ip(unsigned long ip, unsigned int cnt)
{
    …
    preempt_count_sub(cnt - 1);
    if (unlikely(!in_interrupt() && local_softirq_pending())) {
        do_softirq();
    }
    preempt_count_dec();
    …
}


抢占计数器


在介绍“禁止/开启软中断”之前,首先了解一下抢占计数器这个背景知识。
每个进程的 thread_info 结构体有一个抢占计数器: int preempt_count,它用来表示当前进程能不能被抢占。
抢占是指当进程在内核模式下运行的时候可以被其他进程抢占,如果优先级更高的进程处于就绪状态,强行剥夺当前进程的处理器使用权。
但是有时候进程可能在执行一些关键操作,不能被抢占,所以内核设计了抢占计数器。如果抢占计数器为 0,表示可以被抢占;如果抢占计数器不为 0,表示不能被抢占。
当中断处理程序返回的时候,如果进程在被打断的时候正在内核模式下执行,就会检查抢占计数器是否为 0。如果抢占计数器是 0,可以让优先级更高的进程抢占当前进程。
虽然抢占计数器不为 0 意味着禁止抢占,但是内核进一步按照各种场景对抢占计数器的位进行了划分,如下图所示。
 
其中第 0~7 位是抢占计数,第 8~15 位是软中断计数,第 16~19 位是硬中断计数,第 20 位是不可屏蔽中断( Non Maskable Interrupt, NMI)计数。
include/linux/preempt.h
/*
* PREEMPT_MASK: 0x000000ff
* SOFTIRQ_MASK: 0x0000ff00
* HARDIRQ_MASK: 0x000f0000
* NMI_MASK: 0x00100000
*/
#define PREEMPT_BITS 8
#define SOFTIRQ_BITS 8
#define HARDIRQ_BITS 4
#define NMI_BITS 1
各种场景分别利用各自的位禁止或开启抢占。
(1)普通场景( PREEMPT_MASK):对应函数 preempt_disable()和 preempt_enable()。
(2)软中断场景( SOFTIRQ_MASK):对应函数 local_bh_disable()和 local_bh_enable()。
(3)硬中断场景( HARDIRQ_MASK):对应函数 __irq_enter()和__irq_exit()。
(4)不可屏蔽中断场景( NMI_MASK):对应函数 nmi_enter()和 nmi_exit()。
反过来,我们可以通过抢占计数器的值判断当前处在什么场景:
include/linux/preempt.h
#define in_irq() (hardirq_count())
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)
#define in_nmi() (preempt_count() & NMI_MASK)
#define in_task() (!(preempt_count() & \
(NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)))
#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
| NMI_MASK))
in_irq()表示硬中断场景,也就是正在执行硬中断。
in_softirq()表示软中断场景,包括禁止软中断和正在执行软中断。
in_interrupt()表示正在执行不可屏蔽中断、硬中断或软中断,或者禁止软中断。
in_serving_softirq()表示正在执行软中断。
in_nmi()表示不可屏蔽中断场景。
in_task()表示普通场景,也就是进程上下文。


禁止/开启软中断


如果进程和软中断可能访问同一个对象, 那么进程和软中断需要互斥, 进程需要禁止软中断。
禁止软中断的函数是 local_bh_disable(),注意:这个函数只能禁止本处理器的软中断,不能禁止其他处理器的软中断。该函数把抢占计数器的软中断计数加 2,其代码如下:
include/linux/bottom_half.h
static inline void local_bh_disable(void)
{
    __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET);
}
static __always_inline void __local_bh_disable_ip(unsigned long ip, unsigned int cnt)
{
    preempt_count_add(cnt);
    barrier();
}
include/linux/preempt.h
#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET)
开启软中断的函数是 local_bh_enable(),该函数把抢占计数器的软中断计数减 2。
为什么禁止软中断的函数 local_bh_disable()把抢占计数器的软中断计数加 2, 而不是加1 呢?目的是区分禁止软中断和正在执行软中断这两种情况。执行软中断的函数__do_softirq()把抢占计数器的软中断计数加 1。如果软中断计数是奇数,可以确定正在执行软中断。
注意:local_bh_enable() 在硬中断或者关闭硬中断时使用有可能出现问题,会有警告提醒。


 挂起的软中断


另一个跟软中断相关的字段是每个CPU都有一个32位掩码的字段
typedef struct {
    unsigned int __softirq_pending;
    unsigned int ipi_irqs[NR_IPI];
} ____cacheline_aligned irq_cpustat_t;

irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;
EXPORT_SYMBOL(irq_stat);

他描述挂起的软中断。每一位对应相应的软中断。比如0位代表HI_SOFTIRQ.一个注册软中断必须在被标记后才会执行。
宏local_softirq_pending();来获取该字段的值。
宏set_softirq_pending(0);来设置该字段的值。
使用函数raise_softirq()来激活软中断。即把响应的软中断号对应的__softirq_pending中的位置1。表示该软中断被挂起。如果当前CPU不在中断上下文中,唤醒内核线程ksoftirqd来检查被挂起的软中断,然后执行相应软中断处理函数。
内核在如下几个点上检查被挂起的软中断:
1、当do_IRQ() 完成硬中断处理时调用irq_exit()时调用do_softirq()来处理软中断。
2、当一个特殊内核线程ksoftirqd/n被唤醒时,处理软中断。
3、当调用local_bh_enable()函数激活本地CPU的软中断时。条件满足就调用do_softirq() 来处理软中断。

相关文章:

linux 内核软中断介绍

在介绍软中断之前&#xff0c;先来介绍一个概念&#xff1a;中断下半部&#xff1a; 为了避免处理复杂的中断嵌套&#xff0c;中断处理程序是在关闭中断的情况下执行的。可是&#xff0c;如果关闭中断的时间太长&#xff0c;可能导致中断请求丢失。例如周期时钟每隔 10 毫秒发送…...

软考:2024年软考高级:软件工程

软考&#xff1a;2024年软考高级: 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &#xff08;1…...

Kubernetes(K8s)_15_CNI

Kubernetes&#xff08;K8s&#xff09;_15_CNI CNI网络模型UnderlayMAC VLANIP VLANDirect Route OverlayVXLAN CNI插件FlannelCalico CNI配置内置实现 CNI CNI(Container Network Interface): 实现容器网络连接的规范 Kubernetes将网络通信可分为: Pod内容器、Pod、Pod与Se…...

python 生成器的作用

1. 生成器 参考&#xff1a; https://www.cainiaojc.com/python/python-generator.html 1.1. 什么是生成器&#xff1f; 在 python 中&#xff0c;一边循环一边计算的机制&#xff0c;称为生成器&#xff1a;generator. 1.2. 生成器有什么优点&#xff1f; 1、节约内存。p…...

第十五届蓝桥杯(Web 应用开发)模拟赛 2 期-大学组(详细分析解答)

目录 1.相不相等 1.1 题目要求 1.2 题目分析 1.3 源代码 2.三行情书 2.1 题目要求 2.2 题目分析 2.3 源代码 3.电影院在线订票 3.1 题目要求 3.2 题目分析 3.3 源代码 4.老虎坤&#xff08;不然违规发不出来&#xff09; 4.1 题目要求 4.2 题目分析 4.3 源代码 …...

图解系列--HTTPS,认证

确保 Web 安全的HTTPS 1.HTTP 的缺点 1.1.通信使用明文可能会被窃听 加密处理防止被窃听 加密的对象可以有这么几个。 (1).通信的加密 HTTP 协议中没有加密机制&#xff0c;但可以通过和 SSL&#xff08;Secure Socket Layer&#xff0c;安全套接层&#xff09;或TLS&#xff…...

element plus中表格的合计属性和例子

在 element plus 表格中&#xff0c;您可以使用 summary-method 属性来指定一个函数&#xff0c;计算表格中列的合计或平均值等。该函数应该返回一个对象&#xff0c;其中包含每个列的合计值。例如&#xff0c;如果您的表格数据是这样的&#xff1a; [{ name: John, age: 20, …...

计网Lesson1笔记

文章目录 几个简单概念计网的发展史阿帕网和RFCTCP/IP 协议互联网协议计网设计OSI 的七层架构TCP/IP 协议簇 几个简单概念 主机(host)&#xff1a;指单个计算机&#xff0c;比如PC&#xff0c;或者其他电子设备。端系统(end system)&#xff1a;指一块区域内的多个主机&#x…...

指针数组以及利用函数指针来实现简易计算器及typedef关键字(指针终篇)

文章目录 &#x1f680;前言&#x1f680;两段有趣的代码✈️typedef关键字 &#x1f680;指针数组&#x1f680;简易计算器的实现 &#x1f680;前言 基于阿辉前两篇博客指针的基础篇和进阶篇对于指针的了解&#xff0c;那么今天阿辉将为大家介绍C语言的指针剩下的部分&#…...

josef JZ-7Y-33静态中间继电器 电压DC220V 板前接线

系列型号&#xff1a; JZ-7Y-201X静态中间继电器&#xff1b;JZ-7J-201X静态中间继电器&#xff1b; JZ-7L-201X静态中间继电器&#xff1b;JZ-7D-201X静态中间继电器&#xff1b; JZ-7Y-201静态中间继电器&#xff1b;JZ-7J-201静态中间继电器&#xff1b; JZ-7L-201静态中…...

Java第二十章 ——多线程

本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 在这之前&#xff0c;首先让我们来了解下在操作系统中进程和线程的区别&#xff1a;   进程&#xff1a;每个进程都有独立的代码和数据空间&#xff08;进程上下文…...

【超强笔记软件】Obsidian实现免费无限流量无套路云同步

【超强笔记软件】Obsidian如何实现免费无限流量无套路云同步&#xff1f; 目录 一、简介 软件特色演示&#xff1a; 二、使用免费群晖虚拟机搭建群晖Synology Drive服务&#xff0c;实现局域网同步 1 安装并设置Synology Drive套件 2 局域网内同步文件测试 三、内网穿透群…...

【Linux小项目】实现自己的bash

0. bash原理介绍 bash实际上就是一个负责解析输入字符串工具. 我们需要做的事是这些: 手动分割出输入的字符串判断哪些变量是内建命令(自己执行),哪些命令是普通命令(创建子进程执行)实现的功能有: echo export cd 常规指令 输入、输出流重定向 #include<stdio.h> #i…...

客户案例:EDLP助力金融行业打造高效数据防泄露体系

客户背景 某金融机构是一家以金融科技为核心&#xff0c;致力于为客户提供全方位、智能化、便捷化金融服务的综合性企业。公司总部位于南京&#xff0c;业务范围覆盖全国&#xff0c;拥有强大的技术研发团队和优秀的业务精英&#xff0c;为客户提供全方位的金融服务解决方案。 …...

【JavaFX漏扫开发基础】stage窗口/模式/模态

文章目录 stage一、stage窗口二、stage窗口,模式,模态stage模式(5种样式)模态化窗口stage stage其实就是一个窗口,它啥也不是,打开所有windows的程序都会有一个窗口,这个窗口就是javafx里的stage。里面的内容不属于stage,stage就是一个窗口,就这么简单。 Stage is a…...

MySQL进阶知识:锁

目录 前言 全局锁 表级锁 表锁 元数据锁&#xff08;MDL&#xff09; 意向锁 行级锁 行锁 行锁演示 间隙锁/临界锁 演示 前言 MySQL中的锁&#xff0c;按照锁的粒度分&#xff0c;分为以下三类 全局锁&#xff1a;锁定数据库中的所有表。表级锁&#xff1a;每次操…...

linux下的工具---gdb

一、gdb简介 GDB,是The GNU Project Debugger 的缩写&#xff0c;是 Linux 下功能全面的调试工具。 GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&am…...

ESP32-Web-Server编程-JS 基础 2

ESP32-Web-Server编程-JS 基础 2 概述 上节介绍了 JS 编程的基础。如前所述&#xff0c;在 HTML 中&#xff0c;可以通过下述 两种方式使用 JS 程序&#xff1a; 直接在 HTML 文件中通过 script 标签中嵌入 JavaScript 代码。通过 src 元素引入外部的 JavaScript 文件。 在…...

Java Web基础教程

Java Web基础教程 1. Servlet基础 1.1 什么是Servlet Servlet是JavaEE中的标准组件之一&#xff0c;专门用于处理客户端的HTTP请求。并且它必须依赖于Servlet容器&#xff08;Tomcat就是一个标准的Servlet容器&#xff09;才能运行。因为Servlet实例的创建和销毁都是由容器负…...

BUUCTF john-in-the-middle 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 注意&#xff1a;得到的 flag 请包上 flag{} 提交 密文&#xff1a; 下载附件&#xff0c;解压得到john-in-the-middle.pcap文件。 解题思路&#xff1a; 1、双击文件&#xff0c;打开wireshark。 看到很多http流…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...