上海做建材上什么网站好linux wordpress 下载
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:23
当前位置: 首页 > news >正文
上海做建材上什么网站好,linux wordpress 下载,wordpress lights,xp 做网站服务器1.信号入门 1.1生活中的信号 什么是信号? 结合实际红绿灯、闹钟、游戏中的#xff01;等等这些都是信号。 以红绿灯为例子#xff1a; 一看到红绿灯我们就知道#xff1a;红灯停、绿灯行#xff1b;我们不仅知道它是一个红绿灯而且知道当其出现不同的状况…1.信号入门 1.1生活中的信号 什么是信号? 结合实际红绿灯、闹钟、游戏中的等等这些都是信号。 以红绿灯为例子 一看到红绿灯我们就知道红灯停、绿灯行我们不仅知道它是一个红绿灯而且知道当其出现不同的状况时我们应该做出怎么样的行为去应对。 识别认识行为产生 对于红绿灯 我们之前受过的教育让我们能够识别这个红绿灯(即使它还未出现在我们眼前)也就是说你能识别红绿灯 当绿灯量了后我们不一定要直接走也可以等一会再走(也就是说接收信号后我们不一定要立刻产生对应的行为) 当红灯亮了之后我们可以玩手机要记得这个时候还是红灯 当红或绿灯亮时我们可以做出其他行为也可以忽略红绿灯 对于信号来说(进程看待信号的方式) 在没有发生的时候进程已经知道发生的时候该怎么处理了信号进程能够认识在遇见信号之前有人在大脑中设置了识别特定信号的方式(进程能够识别一个信号并处理)信号到来的时候进程正在处理更重要的事情这时进程暂时不能立即处理到来的信号进程必须暂时将到来的信号进行临时保存信号到了进程可以不立即处理等在合适的时候处理信号的产生是随时产生的进程无法准确预料所以信号是异步发送的(信号的产生是由别人(用户、进程)产生的在进程收到信号之前进程一直在忙自己的事情并发在跑的) 为什么 停止、删除…系统要求进程要有随时响应外部信号的能力随后做出反应 我们学习信号是学习它的整个生命周期在进程运行期间信号的生命周期分为以下几个阶段 准备、信号的产生、信号的保存、信号的处理 1.2Linux中的信号 用户输入命令,在Shell下启动一个前台进程 用户按下 Ctrl-C ,这个键盘输入产生一个硬件中断被OS获取解释成信号发送给目标前台进程 前台进程因为收到信号进而引起进程退出 #includeiostream #includeunistd.husing namespace std;int main() {while(1){couti am main process…endl;sleep(1);}return 0; } Ctrl-C 产生的信号只能发给前台进程。一个命令后面加个可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像 Ctrl-C 这种控制键产生的信号。前台进程在运行过程中用户随时可能按下 Ctrl-C 而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止,所以信号相对于进程的控制流程来说是异步(Asynchronous)的。 1.3信号的概念 信号是进程之间事件异步通知的一种方式属于软中断 在Linux操作系统中命令kill -l可以查看系统定义的信号列表 上面的数字和名字都可以标识信号名字其实就是宏总共62个信号(没有0、32、33信号) 其中1~31号是普通信号 34~64是实时信号 我们这里只学普通信号 上面我们说到每个信号都有一个编号和一个宏定义名称这些宏定义名称可以在signal.h中找到这些信号各自在什么条件下产生,默认的处理动作是什么,在signal(7)中都有详细说明: man 7 signal 根据我们对Linux的了解信号存放在哪呢既然信号是给进程的而进程又是通过内核数据结构来管理的那么我们可以推断出信号是放在进程的task_struct结构体中 既然他是在PCB中如果创建31变量把信号全存进去那就太浪费了进程中信号的状态分为有或者没有那么我们可以大胆的推断把31个信号存放在一个只有32位整型变量中每一个比特位都代表一个信号。 比特位的位置代表信号的编号 比特位的内容代表进程是否收到信号1表收到0表没收到 那么问题来了内核数据结构的修改这是由谁来完成的 毫无疑问是操作系统毕竟task_struct就是由它来维护的只有OS才有权利去修改它 所以说无论哪个信号最后都是经由OS之手发送给进程的(发送指的是修改进程PCB中存放信号那个变量的比特位) 信号发送的本质就是在修改进程PCB中信号位图 信号处理常见方式概览 1. 忽略此信号。 2. 执行该信号的默认处理动作。 3. 提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号。 2.信号的产生 kill系统调用接口 kill -9 pid //杀死进程 kill -2 pid //终止进程 2.1通过按键产生信号 通过键盘上按一些热键来给进程发送相应的信号比如上面的ctrl c它产生的是2号信号ctrl \产生的则是3号信号 如何进行自定义处理信号呢 信号捕捉 signal sighandler_t 返回值 signum几号信号 handler自定义方法 typedef void (*sighandler_t)(int) #includeiostream #includeunistd.h #includesignal.h #includesys/types.h using namespace std;void handler(int signo) {coutget a sig,number is:signoendl; }int main() {signal(SIGINT,handler);while(1){coutI am activing…,pid:getpid()endl;sleep(1);}return 0; } 设置信号捕捉只需要一次 signal调用完了handler方法不会被立即执行这里只是设置对应的信号的处理方法 这时候我们发现Ctrl C杀不了这个进程了这是因为我们捕捉信号后(信号的处理方式是自定义处理信号)对于2号信号的处理动作变成执行handler方法 2.2调用系统函数向进程发信号 系统调用和命令的名字一样man 2 kill 查看 pid_t pid 要给发信号的pid int sig:要发送的信号编号 返回值发送成功返回0失败返回-1 该系统调用是一个进程给另一个进程发送指定信号可以向任意进程发送任意信号 #includeiostream #includeunistd.h #include string.h #includesignal.h #includesys/types.h using namespace std;int main(int argc, char *argv[]) {if(argc ! 3){cout Usage: argv[0] -signumber pid endl;return 1;}int signumber stoi(argv[1]1);int pid stoi(argv[2]);int n kill(pid, signumber);if(n 0){cerr kill error, strerror(errno) endl;}return 0; } raise给自己发送任意信号 #includeiostream #includeunistd.h #includesignal.husing namespace std; int main() {cout开始运行…endl;sleep(1);int n raise(2);cout运行结束endl;return 0; } abort发信号终止自己(指定信号 6号SIGABRT) 2.3软件条件产生信号 比如管道那时候把读端关闭(没有了写的条件)那么写端也会收到信号关闭(SIGPIPE) 再举个闹钟的例子 alarm unsigned int 返回值 :上一个闹钟剩余秒数 #includeiostream #includeunistd.h #include string.h #includesignal.h #includesys/types.h using namespace std; int g_cnt 0; void handler(int sig) {std::cout get a sig: sig g_cnt: g_cnt std::endl;unsigned int n alarm(5);cout 还剩多少时间: n endl;exit(0); }int mian() {//设定一个闹钟signal(SIGALRM,handler);alarm(5);while(true){g_cnt;}int cnt 0;while(true){sleep(1);cout cnt : cnt , pid is : getpid() endl; //IO其实很慢if(cnt 2){int n alarm(0); // alarm(0): 取消闹钟cout alarm(0) ret : n endl;}}return 0; } 2.4硬件异常产生信号 最后一种产生信号的方式异常 硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。 除零错误引发异常 8SIGFPE void handler(int sig) {coutget a sig:sigendl;exit(1); }int main() {signal(SIGFPE,handler);int a 10;a / 0;while(1){sleep(1);}return 0; } 野指针 11SIGSEGV void handler(int sig) {coutget a sig:sigendl;exit(1); } int main() {signal(SIGSEGV, handler);sleep(1);int *p NULL;*p 100;while(1){sleep(1);}return 0; } 2.5关于信号产生的各种情况的理解 2.5.1键盘产生信号——硬件中断 键盘产生信号 a.按键按下了 b.哪些按键按下了 c.字符输入(字符设备),组合键输入 字符输入abcd 组合键输入CTRL C 键盘驱动和OS联合解释的 OS怎么知道键盘输入了什么数据呢 硬件中断的技术 键盘 将电信号传到CPU的针脚上 通过硬件中断转化位软信号电流CPU再传给OSOS通过中断向量表中以中断号去检索解释 判定是字符就放到缓冲区里面是命令(ctrlc)解释为信号 2.5.2异常(硬件)产生信号——除零、解引用空指针 除零 void handler(int sig) {coutget a sig:sigendl; }int main() {signal(SIGFPE,handler);int a 10;a / 0;while(1){sleep(1);}return 0; } 如果捕捉除零产生的信号不用exit退出进程的话随着CPU时间片的轮转就会再次被调到 CPU中只有一份寄存器但是寄存器的内容属于当前进程的硬件上下文 当进程被切换的时候就有无数次的状态寄存器被保存和恢复的过程 而除0操作导致溢出位置一的数据还会被恢复到CPU中 所以每次恢复的时候操作系统就会识别到并且给对应的进程发送SIGFPE信号这就导致了上面不停调用自定义处理函数不停地打印 如何理解除0 进行计算的是CPU这个硬件 CPU内部有寄存器状态寄存器(位图)有对应的状态标记位、溢出标记位OS会自动进行计算完后的检测如果溢出标记位是1CPU会告诉OS有溢出的问题OS就会来查看问题并且找到出问题的那个进程并且将所识别到的硬件错误包装成信号发送给目标进程本质就是操作系统去直接找到这个进程的task_struct并向该进程写入8信号 野指针异常 对于野指针异常来说实际上也是CPU、OS共同配合的结果 我们所说的野指针指的是虚拟地址虚拟地址和物理地址的转化如果是成功的那么就不会抛出野指针异常如果是失败的那么CPU就会告诉OS出问题了OS就会找到那个进程并发出11号信号让他终止 虚拟地址与物理地址之间的映射是由一个叫MMU的硬件完成的他是一种负责处理CPU的内存访问请求的计算机硬件 页表实际上是页表和MMU的结合而MMU位于CPU中。在讨论中一般会简化称为页表。 当对空指针解引用的时候MMU会拒绝这种操作从而产生异常标志 操作系统拿到MMU产生的异常以后就会给对应的进程发送SIGSEGV信号 3.信号的保存 上面我们提到如果当前进行更重要的工作那么它会将信号进行保存等到合适的时候再做处理那么信号的保存机制是怎么实现的呢 3.1信号常见概念 实际执行信号的处理动作称为信号递达(Delivery)信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞 (Block )某个信号被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作 注意: 阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作 进程PCB中有一张位图用来表示有无收到指定信号 还有一张位图比特位的位置依然是信号编号比特位的内容表示是否阻塞该信号 如1号位图4号信号位置为12号位图4号信号位置为04号信号无阻塞通畅递达 1号位图6号信号位置为12号位图6号信号位置为16号信号阻塞不递达(除非未来解除阻塞) 3.2在内核中的表示 记住三张表 block表位图 pending表位图 handler表函数指针数组 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。在上图的例子中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。 SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。 SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。 如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。本章不讨论实时信号。 3.3三张表匹配的操作和系统调用 在此之前了解一下sigset_t 从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。 因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。 阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略。 sigsett类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset t变量,而不应该对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的 3.3.1信号集操作函数 man sigemptyset: sigsett set信号集变量 int signum信号编号 返回值成功返回0失败返回-1。 函数sigemptyset 初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含 任何有效信号函数sigfillset 初始化set所指向的信号集,使其中所有信号的对应bit置位,表示 该信号集的有效信号包括系统支持的所有信号。 注意,在使用sigset t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。 初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号 sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号 3.3.2sigprocmask 调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。 man sigprocmask int how: 修改方式有三个选项 set: 我们设置号的sigset_t变量 oldset: 输出型参数将修改之前的信号屏蔽字保存到oldset 返回值sigprocmask函数调用成功返回0出错返回-1 3.3.3pending的系统调用sigpending 读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。 man sigpending 4.代码 #include iostream #include signal.h #include unistd.h #include cassert #include sys/wait.h using namespace std;void PrintSig(sigset_t pending) {coutPending bitmap:endl;for(int i31;i0;i–)//i为比特位也是信号编号{if(sigismember(pending,i)){cout1;}else{cout0;}}coutendl; } void handler(int sig) {sigset_t pending;sigemptyset(pending);int n sigpending(pending);//正在处理2号信号assert(n0);cout递达中…endl;PrintSig(pending);coutsig号信号被递达处理endl;}int main() {//对2号信号进行自定义捕捉signal(2,handler);sigset_t block,o_block;//屏蔽2号信号sigemptyset(block);sigemptyset(o_block);sigaddset(block,2);//进入内核int n sigprocmask(SIG_SETMASK,block,o_block);assert(n0);coutblock 2 signal successpid:getpid()endl;int cnt 0;while(1){sigset_t pending;sigemptyset(pending);n sigpending(pending);assert(n 0);//打印pending位图中收到的信号PrintSig(pending);cnt;//解除对2号信号的屏蔽if(cnt10){n sigprocmask(SIG_UNBLOCK,block,o_block);assert(n0);}sleep(1);}return 0; }
- 上一篇: 上海做兼职的网站网站建设创意广告
- 下一篇: 上海做建材上什么网站好长沙房产网签查询系统
相关文章
-
上海做兼职的网站网站建设创意广告
上海做兼职的网站网站建设创意广告
- 技术栈
- 2026年03月21日
-
上海做兼职的网站东莞家具饰品东莞网站建设
上海做兼职的网站东莞家具饰品东莞网站建设
- 技术栈
- 2026年03月21日
-
上海最专业的网站设计制网站建设前期需要做出的准备
上海最专业的网站设计制网站建设前期需要做出的准备
- 技术栈
- 2026年03月21日
-
上海做建材上什么网站好长沙房产网签查询系统
上海做建材上什么网站好长沙房产网签查询系统
- 技术栈
- 2026年03月21日
-
上海做网站吧外贸建英文网站的重要性
上海做网站吧外贸建英文网站的重要性
- 技术栈
- 2026年03月21日
-
上海做网站比较好的公司连锁店进销存管理软件
上海做网站比较好的公司连锁店进销存管理软件
- 技术栈
- 2026年03月21日
