96SEO 2026-02-20 00:03 8
你在网上买了很多件商品再等待不同商品快递的到来。

但即便快递没有到来你也知道快递来临时你该怎么处理快递。
也就是你能“识别快递”
当快递员到了你楼下你也收到快递到来的通知但是你正在打游戏需5min之后才能去取快递。
那么在在这5min之内你并没有下去去取快递但是你是知道有快递到来了。
也就是取快递的行为并不是一定要立即执行可以理解成“在合适的时候去取”。
在收到通知再到你拿到快递期间是有一个时间窗口的在这段时间你并没有拿到快递但是你知道有一个快递已经来了。
本质上是你“记住了有一个快递要去取”
当你时间合适顺利拿到快递之后就要开始处理快递了。
而处理快递一般方式有三种1.
2号信号则会产生一个硬件中断被OS获取解释成为信号发送给目标前台进程前台进程收到信号之后引起进程退出。
可以放到后台运行这样Shell不必等待进程结束就可以接受新的命令启动新的进程。
而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到
标准信号每个信号都有特殊的含义及用途。
后31种34~64信号被称为
实时信号可用于实时应用程序的拓展信号提供了更多的灵活性。
注意中间并没有32和33号信号。
宏如果调用信号既可以通过信号的名称调用也可通过信号的编号调用。
当然这么多的信号并不需要你全部记下来我们在运用的过程中就会知道哪些信号常用哪些不常用。
忽略此信号。
执行该信号的默认处理动作。
提供一个信号处理函数要求内核在处理该信号时切换到用户态执行这个处理函数这种方式称为捕捉(Catch)一个信号。
}我们使用9号信号和2号信号杀死了进程这种发命令做出对应行为的方式
就是进程执行了信号的默认动作。
好似阿熊在十字路口知道红灯停、绿灯行一样。
handler);signum参数传入需要捕捉的信号名字或编号当进程收到与其相匹配的信号时则会调用第二个参数否则不会有任何动作。
handler参数handlder方法此方法为自定义方法当收到signum信号则不会执行该信号的默认动作变为执行该方法。
值得注意的是我们在设置信号捕捉时并不需要将此接口放入循环之中只需要调用该接口一次在整个程序中则一直循环有效。
我们设置一个signal方法做测试
}signal函数执行时并不会立刻对handler执行回调只有当收到对应的信号时才会执行回调。
比如阿熊跟室友打赌输了接下来一周等红绿灯需要听室友的本来红灯停变为了红灯唱歌但是我们并不知道室友什么时候让阿熊唱歌。
也就是说因为
信号的默认处理方式还剩下忽略信号也就是信号发送到进程但是进程对其不管不顾。
在程序中使用捕捉的方式实现信号忽略那么signal第二个参数应该调用
上面我们已经将以kill命令产生信号的方式介绍完了而信号的产生方式还有一种键盘产生信号我们在上面也说了使用
的方式可以终止进程这就是一种键盘产生信号的方式键盘产生信号的流程
当我们把二号信号进行捕捉并且回调函数只对信号进行打印动作我们再使用
除了键盘产生信号我们还可以使用系统调用产生信号Linux中存在
当没有读端时写端会被终止。
管道不具备写的软件条件了所以触发了终止信号这种信号为
seconds);功能用于试着进程闹钟指定时间以秒为单位后向调用它的进程发送
seconds参数表示在多少秒后发送14号新号如果为0则任何未响应的
返回值无符号整形表示上次设置的闹钟还剩余的秒数。
之前未设置闹钟则返回0。
}大概有3万七千次左右虽然我们云服务器配置不高但是3万7千次未免太少了。
我们把打印信息注释掉并且设置一个全局变量让其在循环内一直做对14号信号再进行捕捉捕捉回调方法打印全局变量
这次运行居然有5亿多次累加至于为什么我们前面打印次数如此的少这里我给出两个原因
1.在Linux下一切皆文件前面对屏幕打印文字的行为本质上是对显示器文件进行疯狂打印。
在前后对比下我们能直观的发现其实
2.由于我们是使用了云服务器真正运行并不在本地运行我们向云服务器发送命令以及云服务器将信息从远端发到本地都是经过网络的。
闹钟在被设置的时候其默认动作只会响一次如果我们想要设置多个闹钟我们可以在回调handler方法里再加上n秒的闹钟这样第一次闹钟响了之后进程收到闹钟信号执行回调方法而main函数是被循环卡死的所以往后就每隔n秒响一次闹钟。
0;while(true){sleep(1);std::cout
}如果我们设定一个闹钟需要很久之后才会响应但是我在此期间发送14号信号提前对SIGALRM进行捕捉执行handler方法的回调返回值是什么呢
0;while(true){sleep(1);std::cout
}我们只对闹钟进行了一次kill信号我们第一个闹钟设置了100s而提示信息是每隔一秒打印一次算下来刚好过去5s打印出的返回值为95s而第二次回调的时候闹钟剩余时间就变为0了这也就证实了alarm接口返回值是上一次闹钟剩余时间。
接下来我来解释一下为什么闹钟也能作为软件条件我们知道alarm接口是系统调用接口也就是说设定闹钟实际上是在操作系统内部设定的。
而操作系统中存在的闹钟定然不止一个所以OS一定要对这些闹钟做管理如何管理先描述再组织
根据以往经验闹钟一定是有自己的结构体结构体内有着必要的属性成员那么在结构体的属性成员当中就必定有闹钟的过期时间成员用来记录闹钟的过期时间
}而闹钟的过期时间实际上是一个时间戳一个线性增长的时间。
那我们应该以什么样的结构组织起来这些闹钟呢经常看我博客的小伙伴第一反应很可能是链表。
设置一个双链表按照闹钟过期时间来排序之后我只要找到第一个过期的闹钟那么在此之后必然全部都是过期闹钟。
虽然这种想法很好但是我们有更优解我在很早之前写过一篇博客堆与堆排序
而操作系统就是采用最小堆的方法组织闹钟结构以最小堆的堆顶一定是最近一次即将超时的闹钟。
所以往后OS只需要查找堆顶元素过期了就释放掉再通过堆调整将次要过期的闹钟调整到堆顶。
第五种信号的产生方式程序出了异常操作系统定然不会在放任这个问题进程不管会采取一定的措施OS为了能让程序员知道程序出了问题于是设置了一些常出现的异常信号当进程出现异常时OS将会对进程发送异常信号爆出异常缘由。
异常并不一定是由程序的语法、逻辑问题带来的可很有可能是外部设备出了问题所以异常又被分为
软件异常通常有除零错误或者溢出错误引起的。
而硬件异常通常是有进程访问无效地址引起的一般有段错误等。
具体情况具体分析我们先对除零错误进行模拟
错误想必学C/C的小伙伴对这种报错会经常见到而其对应的异常信号为
硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。
例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释
为SIGFPE信号发送给进程。
再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
键盘产生数据毫无问题但是操作系统是如何对组合键做出特殊处理的OS怎么知道我使用Ctrl
就是要发送2号信号给进程呢我们都知道操作系统向下管理软硬件资源那么键盘硬件资源当然也属于操作系统管理范畴。
所以我们从键盘输入组合键是由操作系统说的算的而你使用的组合键是被OS解释为了命令。
输入方在与键盘解释方为操作系统也就是说键盘输入的到底是普通数据还是特殊命令是由键盘驱动和OS联合解释的。
这么看来操作系统只需要解释我们输入的信息即可但是对于OS来说用户输入的动作一定是异步的。
而我们在日常使用键盘的时候操作系统似乎是优先处理的。
这样对于操作系统的压力是不是有些大了要知道OS可不止需要监测键盘还有其他异步硬件网卡就是典型的例子。
OS并不能保证何时会不会有信息从网络发来。
显然操作系统如果一直对这些异步发生的硬件进行监视的话会将操作系统的性能拉低而操作系统存在的意义就是向下对软硬件资源管理向上为用户提供良好服务。
所以定然不会无时无刻监视这些硬件于是就有人提出了
这张表提前注册对软硬件资源操作的方法。
比如此表的二号下标的方法就是用来读取键盘输入的数据。
而所谓的中断向量表实际上是一个
通过冯诺依曼结构我们知道CPU在数据层面只和内存级打交道。
但是在每个CPU上都存在许多的针脚这些针脚是物理性的在主板上可以和各个硬件相连接包括键盘也是通过CPU的针脚连接的。
每个针脚都有自己的编号。
而未来我们在按键盘时通过针脚使
不管如何键盘和CPU可以通过针脚相互连接而用户在键盘上输入数据时发送高电平就会触发硬件中断此时CPU就可以检测到这个针脚有高电平从而识别到键盘。
而这时CPU中的寄存器会将中断号针脚编号保存在寄存器内部至此硬件的动作就完成了
寄存器收到中断号后被操作系统检测到此时操作系统就会停下手头的工作。
拿着这个中断号从中断向量表中查询中断号就是中断向量表的下标索引对应处理键盘资源的方法进而调用这个方法去收集键盘发来的数据了。
于是就可以把从键盘输入的数据读取到内存当中了。
严格意义上来说键盘文件也是文件OS会先将数据读入到键盘文件的缓冲区里。
读取到的键盘数据经过操作系统对字符的判定判定为数据则发送到当前进程打开的键盘文件缓冲区中而被判定为控制命令的组合键则会被解释为信号比如我输入了Ctrl
C那么OS就会将其解释为2号信号而并非普通字符信息。
这时这个信号就会发送给调用键盘文件的进程从而执行对应的动作。
那么操作系统如何解释控制命令实际上信号在到来时我们在处理更重要的事情暂时不能处理到来的信号所以我们一定需把信号保存到PCB中要知道信号可是有整整62种一个进程可能会存在多个信号所以OS定要对这些信号做管理如何管理先描述再组织
而这些信号则是由位图这结构描述组织的并且这个位图只需要32位比特位因为标准信号只有31种所以32位比特位完全够用。
如果用户通过键盘对当前用户输入了Ctrl
C则会被操作系统解释为2号信号通过位图将第对应的比特位由0置1即可完成OS对进程发送信号。
也就是说操作系统向进程发送信号的本质是对进程PCB的位图进行写入操作!
除零错误SIGFPE以及野指针错误SIGSEGV都属于异常产生的信号首先我们来分析除零错误。
除零错误实际上也就是计算错误在硬件方面计算错误表现在CPU的寄存器上我们知道程序的计算都是在寄存器内完成的寄存器可以存贮少量数据而当计算发生错误CPU停止对进程的操作转而告诉操作系统当前处理的进程发生了计算错误。
在CPU中存在一个标志寄存器EFLAGS/RFLAGS标志寄存器其
操作系统收到CPU发来的信息发现进程不再被调度了于是操作系统就会检查EFLAGS/RFLAGS寄存器的溢出标记位OF从而检测出当前进程出了计算异常于是
}我们把异常信号的默认执行方式进行了捕捉从而执行我们的handler方法回调。
而handler方法我们仅仅打印了一句话所以这个异常信号依旧存在。
我们都知道在CPU中寄存器只有一套而
但是当前进程被我们设置为一直在运行异常在进程中仍然存在这个时候OS又会向OF读取异常数据进而再一次的对当前进程发送8号信号这样不断的循环就导致了上图的结果。
野指针异常是因为非法访问地址而我们通过之前的学习我们知道野指针内的地址一定是虚拟地址而虚拟地址要映射到物理内存需要经过
转化。
而既然存在转化就一定存在转化成功或者失败我们来讨论一下转化失败的情况。
当程序中发生了野指针错误比如对空地址解引用赋值。
此时当CPU执行到该语句的时候会将指针内保存的虚拟地址由MMU和OS经过页表转化为物理地址但是在转化的时候页表中可能没有该虚拟地址的映射或者该映射的物理地址不可被写入无w权限。
此时MMU就会转化失败于是就向cr2寄存器写入出错的虚拟地址cr2将虚拟地址保存。
当进程出现了野指针异常时当前进程就会停止调度OS就会来检查为何当前进程停止调度而CPU对cr2寄存器进行读取发现当前进程出现了野指针错误于是OS就对当前进程发送11号信号SIGSEGV从而终止进程
所以产生信号不论是系统调用还是软件条件亦或者是键盘、异常产生的信号都是由操作系统同一发送的因为OS作为软硬件资源的管理者当进程出现异常时需要对进程做相应的处理这也就是为什么我们在windows下运行一些带有错误的程序时进程会直接终止。
今天的文章到此结束感谢您的观看如果对您有帮助的话还望给博主一个小小的三连呀~~
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback