读书总结-linux系统的信号机制

在看完《linux环境高级编程》一书之后,后来又参考《深入理解Linux内核》一书,觉得信号这个东西实在是太重要了,在我们linux系统中,信号被看做是一种软件中断, 

用来通知进程发生了异步事件,一个阻塞的进程要依靠信号唤醒,程序如果发异常,要靠信号通知内核,总的来说信号在linux系统中非常重要!!!在操作系统中我们使用信号

的目地就是两个:

(1)让进程知道发生了一个特定的事件;

(2)强迫进程执行它自己代码中的信号处理程序;

1.信号安装函数:

signal()函数:

表头文件 #include<signal.h>
功 能:
设置某一信号的对应动作
函数原型 :
void(*signal(int signum, void(*handler)(int)))(int);
或者:typedef void(*sig_t) (int);   sig_t signal(int signum, sig_t handler);
参数说明:
第一个参数signum指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。
第二个参数handler描述了与信号关联的动作,它可以取以下三种值:
(1)一个返回值为正数的函数地址  此函数必须在signal()被调用前申明,handler中为这个函数的名字。当接收到一个类型为sig的信号时,就执行handler 所指定的函数。这个函数应有如下形式的定义:   intfunc(int sig);   sig是传递给它的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。  
(2)SIGIGN   这个符号表示忽略该信号,执行了相应的signal()调用后,进程会忽略类型为sig的信号。
(3)SIGDFL   这个符号表示恢复系统对信号的默认处理。
函数说明 :   signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。当一个信号的信号处理函数执行时,  如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。  
返回值: 返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。

sigcation函数:

头文件:#include <signal.h>
函数原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
参数说明:
signum:要操作的信号。
act:要设置的对信号的新处理方式。
oldact:原来对信号的处理方式。
返回值:0 表示成功, - 1 表示有错误发生。

sigaction数据结构:
struct sigaction{
	void(*sa_handler)(int);
	void(*sa_sigaction)(int, siginfo_t *, void *);
	sigset_t  sa_mask;
	int       sa_flags;
	void(*sa_restorer)(void);
};

在这个结构体中,成员 sa_handler 是一个函数指针,其含义与 signal 函数中的信号处理函数类似。成员
sa_sigaction 则是另一个信号处理函数,它有三个参数,可以获得关于信号的更详细的信息。当 sa_flags 成员的值
包含了 SA_SIGINFO 标志时,系统将使用 sa_sigaction 函数作为信号处理函数,否则使用 sa_handler 作为信号处理
函数。在某些系统中,成员 sa_handler 与 sa_sigaction 被放在联合体中,因此使用时不要同时设置。
sa_mask 成员用来指定在信号处理函数执行期间需要被屏蔽的信号,特别是当某个信号被处理时,它自身会被
自动放入进程的信号掩码,因此在信号处理函数执行期间这个信号不会再度发生。
sa_flags 成员用于指定信号处理的行为,它可以是一下值的“按位或”组合。

◆ SA_RESTART:使被信号打断的系统调用自动重新发起。
◆ SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。
◆ SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程。
◆ SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。
◆ SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
◆ SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数。

相关数据结构:


在上图中,signal是信号描述符,sighand是信号处理程序描述符。在linux系统中,其实并没有线程的概念,无论是fork(),vfork()其底层都是调用clone()函数(这个函数在

深入理解Linux内核的p118业有详细讲述),当我调用fork或是vfork的时候,一个进程会被创建,如果新创建的进程和父进程共享一个页表,那么这个进程就实现了线程的功能,

共享父进程的地址空间,这个时候我们也称之为轻量级进程。所以在task_struct结构中,就会有两个悬挂信号队列,其中signal是共享信号悬挂队列,pending是进程私有悬挂

队列。我们在信号描述符和信号处理描述符中都看到了count字段,它们分别是信号描述符的使用计数器和信号处理程序描述符的使用计数器。它们都是为了统计有多少个进程

共享这两个描述符。因此,对属于同一线程组的每个进程而言,信号描述符中的字段必须都是相同的(《深入理解LInux内核》)。如果一个挂起信号被发送给某个特定进程,那么

这个信号是私有的,如果被发送给了整个线程组,那么它就是共享的。

信号的产生函数:

(1) int raise(int sig);  对当前进程发送指定信号
(2) int pause(void);  将进程挂起等待信号
(3) int kill(pid_t pid, int sig); 通过进程编号发送信号
(4) unsigned int alarm(unsigned int seconds); 指定时间(秒)发送SIGALRM信号。 seconds 为0 时取消所有已设置的alarm请求;
(5)int sigqueue(pid_t pid, int sig, const union sigval val); 类似于kill函数,多了附带共用体 union sigval形数,将共用体中的成员 int sival_int 或 void *sival_ptr 的值传递给 信号处理函数中的定义类型 siginfo_t 中的 int si_int 或 void *si_ptr;
(6)int setitimer(int which, const struct itimerval *value, struct itimerval *oldvalue);  可定时发送信号,根据which可指定三种信号类型:SIGALRM、SIGVTALRM 和SIGPROF;作用时间也因which值不同而不同; struct itimerval 的成员 it_interval定义间隔时间,it_value 为0时,使计时器失效;
(7) void abort(void) 将造成进程终止;除非捕获SIGABORT信号;

当发送一个信号时,这个信号可能来自内核,也可能来自另外一个进程。信号的产生是在信号挂起队列中插入一个sigqueue结构(如上图)。那么信号产生之后,就要递送,在

深入理解LInux内核的p421页中描述如下:

内核强迫目标进程通过以下方式对信号做出反应,或改变目标进程的执行状态,或开始执行一个特定的信号处理程序,或两者都是。

进程处理信号的时机是:每当内核处理完一个中断或异常即将从内核态返回到用户态时,就检查是否存在挂起信号!!!进程处理信号的过程如下:


上图说明了有关捕获一个信号的函数执行流。一个非阻塞的信号发送个一个进程。当中断或异常发生时,进程切换到内核态。

当进程正要返回到用户态前,内核执行do_signal函数,这个函数依次处理信号和建立用户栈,并且将EIP的地址设置为信号处理程序的地址,当进程返回用户态执行时,信号

处理程序就会被执行,当程序终止时,setup_frame或setip_rt_frame函数存放在用户态堆栈中的返回代码就会被执行,这个代码调用sigreturn()或rt_sigreturn()系统调

用,相应的服务例程把正常程序的用户态堆栈硬件上下文拷贝到内核态堆栈,并把用户态堆栈恢复到它原来的状态。当这个系统调用结束时,普通进程就能恢复自己的执行!!


Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值