信号的产生
当用户按终端的某些建时会产生信号,比如当用户按delet或者ctrl+c时产生SIGINT信号,默认动作是中断这个进程。
硬件异常产生信号:除数为0或者无效的内存引用等。
进程调用kill函数将任意信号发送给另一个进程或进程组,但是发送信号的进程必须和接受信号的用户相同或者发送信号的所有者必须是超级用户。
信号的处理动作:
忽略信号,大多数信号都是这种处理动作,但是SIGKILL和SIGSTOP两个信号不能被忽略,因为超级用户要使用这两个信号进行控制进程的终止和停止。
默认动作,表示按照系统的默认处理来进行执行。
捕捉信号,是自定义一个函数,当某个信号到达时按照用户自定义的函数来进行处理。
下面介绍常见的信号
SIGABRT:当调用abort函数时产生此信号,进程异常终止。
SIGALRM:当使用alarm函数设置一个时钟时,当时间到时,便会产生这个信号。
SIGKILL:这是两个不能忽略的信号之一,它向系统管理员提供了一种可以杀死任意进程的可靠方法。
SIGINT:当用户按中断建时,产生这个信号。
SIGPIPE:如果在管道的读进程已经关闭时写管道,便会产生这个信号。
SIGQUIT:当用户按crtl+/时便会产生此信号。
SIGSEGV:表示进程进行了一次无效的内存引用。
SIGSTOP:这是一次作业控制信号,它停止了一个进程。
signal函数
#include<signal.h>
void (*signal(int singo,void (*func(int))))(int);
这个函数有两个参数第一个表示信号的名字是一个整形变量,第二个参数表示一个处理函数的名字,这个函数没有返回值,并且这个函数有一个整形参数。最后这个函数的返回为指向原来默认操作的指针。
SIGCHLD信号
这个信号是一个子进程的状态发生变化时会产生这个信号,比如当一个子进程结束时便会向父进程发送这个信号,并且父进程默认忽略这个信号,我们下面做一个测试。
#include"head.h"
void sigchld(int signo)
{
printf(“sigchld operate have changed\n”);
}
int main()
{
pid_t pid;
void *a;
if(signal(SIGCHLD,sigchld)SIG_ERR)
{
printf(“signal error\n”);
exit(0);
}
if((pid=fork())<0)
{
printf(“create process error\n”);
exit(1);
}
else if(pid0)
{
printf(“child process end\n”);
}
waitpid(pid,NULL,0);
}
结果:
root@ubuntu:/home/sun/project/10# ./sigchld
child process end
sigchld operate have changed
函数kill和raise
函数原型
#include<signal.h>
int kill(pid_t pid,int signo)
int raise(int signo)
返回值:成功发挥0,失败返回-1
raise函数表示将signo发送给本进程
kill函数可以将信号发送给指定进程,有两个参数第一个表示发送进程的id,第二个表示发送的信号。
kill函数的pid的几种情况
pid>0表示将信号发送给进程号为pid的进程
pid==0将信号发送给和发送信号进程在同一组的所有进程
pid<0表示将信号发送给进程id为pid的绝对值的进程
pid==-1表示将信号发送给所有这个进程有权限发送的进程
raise(signo)和kill(getpid(),signo)的功能是相同的。
#include"head.h"
int main()
{
sleep(3);
kill(getpid(),SIGINT);
sleep(100);
return 0;
}
三秒后进程结束
函数alarm和pause
函数原型
#include<unistd.h>
unsigned int alarm(unsigned int second)
返回0或者剩余的时间
这个函数的作用便是设置一个定时器,这个函数只有一个参数表示秒数,设置在second秒后由内核想进程发送一个SIGALRM信号,这个信号的默认处理动作是结束这个进程,这个函数的正常返回未0,在一个进程中只能设置一个定时器,当设置第二个定时器时将返回第一个定时器剩余多长时间,我们可以使用alarm(0)来取消一个定时器。
#include"head.h"
int main()
{
unsigned a=alarm(3);
printf("%d\n",a);
return 0;
}
这个表示正常返回,返回值为0
#include"head.h"
int main()
{
alarm(10);
sleep(3);
unsigned a=alarm(3);
printf("%d\n",a);
return 0;
}
结果输出7,表示第二个alarm函数的返回值
#include"head.h"
int main()
{
alarm(6);
sleep(2);
alarm(0);
printf(“alarm stop\n”);
return 0;
}
结果:
root@ubuntu:/home/sun/project/10# ./alarm2
alarm stop
函数原型
#include<unistd.h>
int pause()
返回值:-1,errno设置为EINTR
这个函数的作用便是将一个进程挂起,当有信号传递到这个进程时并且执行完信号处理程序时返回。