Linux下的信号(一)

来源:互联网 发布:软件产品设计流程 编辑:程序博客网 时间:2024/05/16 05:50

信号主要是用于不同进程之间进行通信的机制,进程之间的相互协作也正是通过发送信号来完成的,而信号的本质就是修改PCB中关于信号变量的某个比特位(至于为什么是一个比特位,随后就会做出解释)

 

查看当前系统定义的信号列表:kill -l

 


请看仔细咯,上面的信号量列表个数并不是64个,而是62个


信号分类


普通信号:1——31号信号

实时信号:34——64号信号

 

在我们的学习中主要研究的是1——31号普通信号,因此在对应的PCB中采用位图这个数据结构,就可以表示一个信号的存在与否,这也解释了上面的信号量本质为什么是修改PCB中管理信号的变量的一个比特位

 

背景知识

 

前台进程:基本上不和用户交互,优先级稍微低一些

后台进程:需要和用户进行交互,需要较高响应速度,优先级别稍微高一些

 

信号产生的条件

 

(1)用户在终端按下某些组合键,终端驱动程序会发送信号给前台信号;



(2)硬件异常产生信号,有硬件检测并发送给内核,然后由内核向当前进程发送信号;


进程终止的根本原因就是因为收到信号


(3)使用kill命令发送信号给其他进程;

 

信号的三种处理方式

 

(1)忽略此信号(大多数信号都可以使用这种方式处理)


特例:SIGKILL和SIGSTOP

原因:他们向超级用户提供一种使进程终止或停止的可靠方法,同时,如果忽略某些由硬件异常产生的信号,则进程的行为是未定义的。


(2)直接执行进程对于该信号的默认动作(与信号的种类有关,大多数会直接终止该进程)


(3)捕捉信号(执行自定义动作,使用signal函数,而要做到这一点必须调用handler用户函数,可以执行用户希望做的事情)


特例:不能捕捉SIGKILL和SIGSTOP函数

原因:试想一下,如果所有的信号都可以被捕捉,那么当非法用户入侵时就会导致进程永远杀不掉,因此系统在最初设计这些信号时,就特意留出了不能被捕捉的信号。

 

#include <signal.h> typedef void (*sighandler_t)(int);                    //具体执行动作的函数sighandler_t signal(int signum, sighandler_t handler); //第一个参数,信号编号,第二个参数,信号执行的动作


代码示例:

 

#include<stdio.h>#incldue<stdlib.h>#include<signal.h>void* mysig(int sig){     printf("pid: %d,sig is %d\n",getpid(), sig);}int main(){     signal(2,mysig);     retrurn 0;}


查看当前的mysignal进程状态

 

 

利用core dump(核心转储)定位错误地方


error:error.c        gcc -o error error.c.PHONY:cleanclean:        rm -f error

 

#include<stdio.h>int main(){        int* p=10;        *p=5;        printf("%d",(int)p);        return 0;}

 

运行结果:



先试用ulimit -a来查看当前系统下各种资源的上限

 

 

系统默认的大小是0,而core dump的作用是,当一个进程正在运行,突然收到一场错误时,操作系统为了方便调试,将内存中的进程数据存储到硬盘中。但是以死循环的形式将错误不停的存储时,后果可想而知。

 

修改ulimit -c [size]修改core dump的大小

 

 

修改core文件之后,再次编译查看时,就会有一个很大的core文件产生(其后的数字表示进程号)

 

 

使用core-file core.xxxx定位错误

 


Linux下的信号(二)

http://blog.csdn.net/double_happiness/article/details/72897148

原创粉丝点击