学习系统编程No.26【信号处理实战】

这篇具有很好参考价值的文章主要介绍了学习系统编程No.26【信号处理实战】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言:

北京时间:2023/6/26/13:35,昨天12点左右睡觉,本以为能和在学校一样,7点左右起床,设置了7点到8点30时间段内的4个闹钟,可惜没想到啊,没醒,直接睡到了12点,看来下次不能给自己太高的期望,哈哈哈!在家没办法呀,习惯睡到12点了,想要解决这个问题,最好的方法就是早睡,今天争取在11点前睡觉,然后看看明天能不能在8点前起床,作息必须调整成和学校一样,这样才不会耽误我们更新博客,上篇博客是这个月16号就要写完的,可惜硬是拖到25号才发,由于考试和放假等原因,摆烂至今,哎,无奈!但,一切还有待挽回,只要把这个暑假给利用好,那么就无伤大雅,无论是为了今天能够早睡,还是实现自己的期望,正式进入该篇博客的主题,剩余相关信号产生和信号保存、信号处理等知识讲解。

学习系统编程No.26【信号处理实战】

信号产生剩余知识

上篇博客由于各种原因,剩下了许多知识没有讲解完,那么只能在该篇博客中进行回顾和深入,但本质都已经讲解过了,只不过是进行一定的深入和概念转换而已,所以接下来,我们就把先把上篇博客剩余有关知识进行讲解,然后再学习有关线程相关的知识吧!

什么是云服务器
谈到云服务器,当时在学习Linux时,购买了一个腾讯云的云服务器,至今已经快要过期了,当时只购买了半年,早知道买一年甚至两年了,续费价格挺让我苦恼的,哈哈哈!不过问题不大,在该篇博客我们只要知道,云服务器是基于虚拟化技术的计算资源,通过云平台提供灵活的计算、存储和网络资源。可以为用户提供一种高效、可靠和经济的方式来托管应用程序、运行服务以及处理大规模的计算任务,优势在于灵活性、可扩展性、弹性伸缩以及简化的部署和管理过程。云服务器这么好用,也这么有用,可惜我对其功能的使用方式可以说是一窍不通,只知道用来登录一下Linux系统,哈哈哈,想笑,具体能玩出什么花样来,在没接触过之前,我也不晓得,但是我知道肯定很厉害,具体需要我们深入学习,等接触了网络等知识时,才能有一定的自我理解,并且云服务器相关知识在之后的博客中,我们也会重点了解,这里不过多介绍。

获取core dump标志位
无论是在上篇博客,还是之前学习有关进程控制和进程等待相关知识时,我们都知道,可以通过waitpid获取到一个进程的退出状态,并且由于该退出状态是一个位图结构,该位图结构又包含了退出信号、退出码和core dump标志位等信息,所以此时我们就可以通过对该退出状态的位图结构进行位运算,得出对应的退出信号、退出码和core dump标志位,如下代码所示:
学习系统编程No.26【信号处理实战】
注意:如果是使用云服务器,同理,一定先要将对应的核心转储功能给打开,只有打开之后,发送对应的Core行为状态信号,操作系统才会发生核心转储功能,如上图所示,具体关闭和打开云服务去上的核心转储功能,在上篇博客中我们有详解介绍,这里就不多做赘述,并且core dump标志位,我们具体也见到了,有关core dump相关知识,我们就讲到这里,下面正式进入另一块重要知识学习。

什么叫做阻塞信号

注意,此时的这个阻塞信号和我们之前学习的有关进程状态(阻塞,挂起)毫无关系,该知识是一块全新的知识,并没有任何相似知识,要进行区分,不过,这块知识和我们之前学习有关信号在进程pcb中存储肯定是有一定关系的,在之前的博客中,我们就学习了相关信号执行和存储等知识,当然有信号存储,信号执行,那么肯定存在着信号阻塞或者是信号忽略等概念的存在,所以下述知识也算是在完善信号相关知识,具体如下所述。

信号其它相关常见概念

同理,在之前,我们学习了相关信号执行动作(默认、自定义、忽略),但是在计算机中,信号在被执行中,还存在着许多的概念,如信号递达,信号未决,信号阻塞等!虽然听着这些概念非常的高大上,但本质这些概念分别表示什么内容,我们都已经熟练掌握了,如下:

信号递达(delivery):执行信号的处理动作,当然也就是上述所说的三种信号执行动作,默认处理动作,自定义处理动作,忽略动作本质都是一种信号递达行为,总的来说信号递达就是收到信号后会执行某一个动作
信号未决(pending):信号从产生到递达之间的状态,当然也就是之前所说信号产生之后,操作系统将信号编号写入进程pcb对应位图结构,等待进程执行该信号的过程
信号阻塞:同理,进程可以选择阻塞某个信号,被阻塞信号将保持在未决状态,直到进程解除对该信号的阻塞,该信号才可被递达(注意忽略不叫做阻塞)

那么具体如何理解进程阻塞信号呢?
本质就是因为在信号递达过程中,操作系统可以向进程pcb中写入任意一个信号,那么这也就决定着,操作系统可以选择让该进程阻塞某一个或者多个信号,这样做的意义在于,当该进程会导致操作系统产生某个信号,或者操作系统会发送某个信号给该进程,那么由于该进程对该信号设置了阻塞,此时该进程就允许不再递达该信号,直到该信号被解除相应的阻塞状态,该信号才允许被递达。注意:如果某一个信号处于阻塞状态,那么该信号一定未决,但信号阻塞并不会影响信号未决(好比你不做作业,但是并不影响老师给你布置作业),并且信号阻塞也叫作信号屏蔽。

如何理解忽略动作
在日常生活中,忽略动作表示你知道某件事需要你去完成,但你却消极对待,不重视,不关心,例如:老师布置了一份作业,你将作业记在了笔记本上,但你在完成它时,就直接用线划掉,表示自己完成了该作业。而在Linux操作系统看来,忽略动作,本质就是使用signal系统调用接口让某一个信号的默认执行动作从终止进程变为忽略,也就意味着忽略动作就是将某个信号通过signal函数接口将其默认动作设置为SIG_IGN,当然此时的SIG_IGN表示的就是信号忽略。同理注意:虽然信号忽略和信号阻塞都是什么都不干,但是信号阻塞,那么该信号一定是处于非递达状态,而信号忽略,该信号却是处于递达状态。

信号保存

搞定了上述知识,此时进入信号相关知识中最后一部分,当然也是最重要的一部分知识,信号保存,无论是在上述讲解中,还是在之前的学习过程中,都一直强调进程保存信号的知识和操作系统向进程写入信号的知识,操作系统是如何写入信号,我们通过对位图结构的理解,有了一定的了解,但是对于进程pcb中的位图结构具体是如何保存该信号,我们并不清楚,所以接下来我们就深入探讨一下有关进程进行信号保存的相关知识吧!如下:

首先明白,对于操作系统来说,管理一个进程,最重要的就是管理该进程的进程pcb,而某一个进程的进程pcb是非常复杂的,其中包含了该进程对应的各种数据,内容较为繁杂,其中对于存储信号来说,在进程pcb(task_struct)中,存在着一张表,如下图所示:
学习系统编程No.26【信号处理实战】
如上图所示,此时我们就意识到,之前我们了解的有关信号保存,只是让对应的信号编号通过操作系统写入到pending位图中,同理pending位图中比特位的位置表示的就是对应的信号编号,比特位的内容表示的就是该信号是否被写入。并且发现除了pending表,还存在另外两种表,其中阻塞表表示该信号是否被阻塞,只有在未被阻塞的前提下,该信号才会发生递达,如果该信号被阻塞,那么就算该信号存在于pending表中,也不会被递达,最后就是自定义动作表,该表表示的是一个数组,该数组的数组下标同理表示信号编号,下标内容表示信号递达动作(函数指针),同理可以是默认动作,也可以是自定义动作或者忽略动作,具体该下标中的递达动作是什么,我们可以通过系统调用接口signal进行替换,但一般是SIG_DFL(默认动作)。此时明白了上述三张表分别代表什么之后,我们就可以发现,一个信号在进程中是如何被保存和一个进程是如何识别一个信号,也就是明确该信号应该如何被执行,是否阻塞,是否执行默认动作,并且可以很好的明白,底层实现代码本质就是在通过判断语句(if)进行判断,最终判断一个信号符合那种情况,然后被进程执行而已。

详解信号列表
学习系统编程No.26【信号处理实战】

什么是sigset_t

明白上述pending和block两个位图结构,是允许我们直接进行控制的,只不过由于它们属于位图结构,所以如果我们想要对其进行控制,就需要使用位图数据类型,当然也就是sigset_t数据类型,并且明白sigset_t也叫做信号集,而用于控制pending位图结构的叫做未决信号集,用于控制block位图结构的叫做阻塞信号集,本质来说,sigset_t就是用于控制内核中的block和pending两张位图结构表,但,由于我们自己进行位运算,容易出现一系列的问题,为了避免这个问题,操作系统提供了许多的位运算接口给我们使用,如下代码所示:

int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);

总而言之:上述几个接口就是用于控制位图结构,也就是对sigset_t类型的数据进行增删查改,可以通过上述接口设计出任意的符合我们要求的位图结构。

信号集读取控制函数

明白了上述知识,此时我们就知道,对于位图结构来说,也存在相对应的增删查改操作,可以使用相对应的接口对位图结构进行控制,所以同理上述所说,如果我们需要控制block或者pending表,就可以使用相对应的接口,但是此时会面临一个问题,那就是如何获取到block或pending位图结构,并且将其修改呢?所以接下来就涉及到两个信号集读取控制函数,如下所述:

1.sigprocmask
其中 sigprocmask 是一个用来读取并且修改block表的函数接口,头文件signal.h,基本调用方式:int sigprocmask(int how, const sigset_t *set, sigset_t *oset);其中第一个参数how表示想怎么改,其中附带了三个参数选项,SIG_BLOCK、SIG_UNBLOCK、SIG_SETMASK,其中SIG_BLOCK表示的是将某一个信号编号添加到阻塞信号集(block)中,而SIG_UNBLOCK表示的是将某一个信号从阻塞信号集中解除阻塞,SIG_SETMASK表示的是直接将一个位图结构替换阻塞信号集(block位图),具体如下代码所示:
学习系统编程No.26【信号处理实战】
从上图我们就可以发现,在sigprocmask中,该接口的第二个参数表示的是一个sigset_t类型的位图结构,该位图结构的目的就是用于控制block位图结构,通过SIG_BLOCK、SIG_UNBLOCK、SIG_SETMASK等选项实现与其对应的位运算,并且其中SIG_BLOCK表示的就是mask|=set,SIG_UNBLOCK表示的就是mask&=~set,SIG_SETMASK表示的就是mask^=set,而最后一个参数oset表示的就是没有进行位运算之前的block位图结构,作为的是一个输出型参数,方便之后将位图结构复原(当然也就是解除阻塞状态或者是重新将某个信号编号设置为阻塞状态),本质也就是获取调用sigprocmask接口之前的block位图结构。

2.sigpending
明白上述sigprocmask接口是用于读取和控制阻塞信号集(block表),那么同理,pending表也需要被读取和控制,此时控制pending表的接口就叫做 sigpending ,同理头文件signal.h,基本使用方式:int sigpending(sigset_t* set);显然此时通过该调用方式,发现,该接口只有一个参数,所以此时间接明白,该接口不允许我们直接修改pending位图,而只支持我们获取pending位图,和sigprocmask接口不同的是,sigprocmask接口不仅支持我们获取block位图结构,还支持我们修改该位图结构,本质也就是操作系统支持我们对某个进程进行阻塞某个信号的操作,而不支持我们直接向进程写入信号的操作,所以该接口的目的非常的简单,为了提供我们pending位图结构,也就是可以让我们知道,目前该进程中有哪些信号正处于pending(未决)状态。如下代码所示:
学习系统编程No.26【信号处理实战】
当然由于上述我们在屏蔽信号时,只屏蔽了2号信号,所以才会导致发送2号信号该进程不被终止的同时,pending位图的2号比特位由0置1,当然同理,我们也可以将1到31号信号全部给屏蔽掉,但是此时会发现,有的信号就算是被屏蔽了,进程也会执行该信号的默认动作,所以明白,对于操作系统和进程来说,有的信号不允许用户自定义控制,就算该信号被阻塞,其依然需要执行。文章来源地址https://www.toymoban.com/news/detail-503370.html

总结:有关信号产生、信号保存和信号处理相关知识该篇博客就介绍到这啦,因为时间关系,剩余知识同理下篇博客见,啦啦啦啦!

到了这里,关于学习系统编程No.26【信号处理实战】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数字信号处理教程学习笔记1-第2章时域中的离散信号和系统

    信号处理的任务示意方框图 模拟信号和数字信号分别是啥样的,有啥区别

    2024年01月22日
    浏览(54)
  • 学习系统编程No.13【文件系统】

    北京时间:2023/3/31/7:48,该篇博客在两天前本就应该产出,但是摆烂谁拦得住,所以呜呜呜!本以为欠的钱也要快还完了,没想到啊,越欠越多,烦人!但是,欠的都是小钱,不像以前,欠的是大钱,所以也不怎么打紧,慢慢还啦!这周的榜估计是保不住了,具体还要看看周

    2023年04月15日
    浏览(72)
  • 学习系统编程No.7【进程替换】

    北京时间:2023/3/21/7:17,这篇博客本来昨天晚上就能开始写的,但是由于笔试强训的原因,导致时间用在了做题上,通过快2个小时的垂死挣扎,我充分意识到了自己做题能力的缺陷和运用新知识的缺陷,所以我需要把重心给转移一下了,以后做题才是我的头号目标,虽然我在

    2024年02月21日
    浏览(40)
  • 学习系统编程No.25【核心转储实战】

    北京时间:2023/6/16/8:39,实训课中,大一下学期最后有课的一天,还有两天就要期末考啦!目前什么都还没有复习,不到星期天晚上,咱不慌,小小挂科,岂能拦得住我补考,哈哈哈!小事,莫慌,该篇博客出炉之时,就是我复习之日,临阵磨枪不快也光,这方面我是专业的

    2024年02月11日
    浏览(46)
  • 学习系统编程No.12【基础IO】

    北京时间:2023/3/28/7:19,周二,早八的一天,难过!终于进入C站周创作榜啦!开心!给大家推荐一首歌《盛夏的果实》,给我的感觉非常的放松,劳逸结合,音乐非它莫属,为了下周周榜可以继续前进, 今天我们就来学习一下基础IO的知识吧! 从上篇博客,我们明白,重定向

    2023年04月21日
    浏览(55)
  • 学习系统编程No.17【vscode实战】

    北京时间:2023/4/11/7:25,昨天11点洗澡,洗完直接睡,导致现在头发愈发不能看,So,平头时刻将要来临,头发太长真的很不方便,昨天已经更文啦!这个星期一定要实现日更,因为我发现,不日更,或者说更文不积极,根本上不了热榜,所以今天又有新文章和大家见面哦!

    2023年04月14日
    浏览(86)
  • 学习系统编程No.14【动静态库】

    北京时间:2023/4/3/7:06,刚刚晨跑回来,为了摆脱困意,刷了一下视屏,哈哈哈!我发现我每次刷视屏都是被迫的,都是看到某个感兴趣的标题,然后点进去一看,就不能自拔了,所以我下次得把消息提醒给全部关掉,烦人;并且全宿舍英文4级都报上了,就我没报上,真的是

    2023年04月09日
    浏览(54)
  • 学习系统编程No.16【进程间通信】

    北京时间:2023/4/9/20:44,昨天,也就是这个周末的星期六,就是传说中的蓝桥杯,哈哈哈!摆烂,做题方面真不怎么行,可惜,当初可能是年少轻狂或者说是没什么经验阅历,希望在有了这次的经历之后,明年的今天,能够更加从容吧!谁让我们平时不怎么做题呢?准确的来

    2023年04月15日
    浏览(48)
  • 学习系统编程No.33【生产消费模型】

    北京时间:2023/7/22/14:27,现实和预期往往相差是巨大的,哈哈哈!白天睡不醒,晚上睡不着,就像一个夜猫子一样。熬夜耍手机,我真的是专业的,已经连续好久没有正常睡过觉了。怀念学校里的日子,每天都有人激励我早睡和早起,此处@谢xx,不知他最近的学习状态如何,

    2024年02月14日
    浏览(38)
  • 学习系统编程No.32【线程互斥实战】

    北京时间:2023/7/19/15:22,昨天更新完博客,和舍友下了一会棋,快乐就是这么简单,哈哈哈!总体来说,摆烂程度得到一定的改善,想要达到以前的水准,需要一定的契机,毕竟人生在世,快乐最重要是吧!更文带给我的快乐已经没有那么多了,虽然欠了非常多的作业,非常

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包