Unix信号机制的简单介绍

Unix信号机制的简单介绍,第1张

信号是一种软中断,它提供了异步响应和处理事件的机制。比如用户在终端上按下

Ctrl-C终止程序运行,此时运行的程序就会收到对应的信号,然后终止程序运行。

运行程序,然后按Ctr-c键会得到如下结果:

一般情况下,按下Ctrl-C后程序直接退出,这个简单的例子里我们捕获了终止信号,进行

了自己的处理:打印出一段信息,然后main函数运行完毕。事实上,我们完全可以进行自由

地进行其他处理,比如不退出运行,虽然这不符合该信号的常规定义。

下面我们从这个简单的例子出发,详细分析

根据是否会被信号中断,系统调用分为两类:“慢”系统调用和其他。“慢”系统是一类可能

永远阻塞调用者的系统调用。

如果线程捕获了一个信号,但线程被阻塞在一个“慢”系统调用(例如从网络中读取一些数据)

,此时系统调用会被中断,返回错误且 errno 被设置为 EINTR 。

这样设计的原因是我们认为当一个信号被捕获到时,说明发生了重要的事件,应当唤醒线程

来处理事件。

这样的设计也带来了一些问题,因为某些读取调用属于可中断的系统调用,每次返回时,

程序都要判断是否是因为捕获信号导致的失败,如果是,需要进行重试。这样一来编码

非常繁琐,因此有些系统对一些“慢”系统调用支持自动重试。

信号处理函数的安全性问题产生的原因在于,信号可能随时被捕获,信号被捕获时,线程

可能处于任何状态,因此,在信号处理函数中,调用某些函数,可能导致不可预测的危险

行为。

比如,当信号被捕获时,线程正在调用 printf ,如果信号处理函数中也调用 printf 函数

可能会导致不可预测的风险。

风险的原因和 printf 函数的实现密切相关。因为 printf 函数包含了一个缓冲区,缓冲区

里包含了很多状态变量,当正在调用 printf 被中断时,缓冲区中的很多变量处于中间状态

如果在信号处理函数中在调用 printf 的话,就会导致不可预测的危险。

确保信号处理函数安全性的做法是在信号处理函数内部,只能调用可重入的函数(reentrant

function)。

第一步:在vi中书写程序father2.c,代码如下:

#include<stdio.h>

#include<time.h>

#include<sys/types.h>

void show_systime(void)

main()

{

pid_t pid

int i

pid=fork()

if(pid<0)

{

perror("filed ehwn creating new process\n")

exit(1)

}

else

if(pid==0)

{show_systime()<br/><br/>}

else

{wait(NULL)<br/><br/>for(i=1i<=100i++)<br/><br/>{printf("%d",i)<br/><br/>printf("\n")}

}

}

void show_systime(void)

{

time_t t

if(time(&t)==((time_t)-1))

{printf("Error when getting time!\n")<br/><br/>exit(1)}

else{

char *tt

tt=ctime(&t)

printf("now is %s\n",tt)}

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/8164234.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-14
下一篇2023-04-14

发表评论

登录后才能评论

评论列表(0条)

    保存