3、信号
用户进程对信号的响应方式:
* 忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。
* 捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。
* 执行缺省操作:Linux对每种信号都规定了默认操作
1、kill: 向进程发射信号
#include <signal.h>
int kill(pid_t pid, int sig);
参数:
pid: 进程号, 0:同一个进程组, -1:信号发给所有的进程表中的进程(除了进程号最大的进程外)
sig: 信号
返回值:
成功: 0
失败: -1, 并设置errno
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char *argv[])
{
pid_t pid = fork();
if (pid < 0)
{
perror("fork");
return -1;
}
else if (0 == pid) //child
{
sleep(5);
printf("child: pid = %d\n", getpid());
exit(10);
}
printf("parent!\n");
sleep(2);
if (0 > kill(pid, SIGKILL)) //向进程发射信号
{
perror("kill");
return -1;
}
int wstatus;
pid = wait(&wstatus); //获取子进程退出状态
if (WIFEXITED(wstatus)) //判断是否是正常退出
{
printf("Child process exit normally!\n");
printf("exit: %d\n", WEXITSTATUS(wstatus)); //获取退出值
}
else
printf("Chils process exit unnormally!\n");
printf("wait: pid = %d\n", pid);
return 0;
}
2、raise: 向自己进程发射信号
#include <signal.h>
int raise(int sig);
参数:
sig: 信号
返回值:
成功: 0
失败: 非0
3、alarm: 闹钟函数
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
参数:
seconds: 秒
返回值:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
alarm(3);
sleep(2);
printf("%u\n", alarm(5));
while (1)
{
sleep(1);
printf("1s go out...\n");
}
return 0;
}
4、signal:注册信号的处理方式
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数:
signum: 信号
handler:
SIG_IGN: 忽略信号
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char *argv[])
{
signal(SIGINT, SIG_IGN);
while (1)
{
printf("hello world!\n");
sleep(1);
}
return 0;
}
SIG_DFL: 缺省信号
函数的入口地址: 捕获信号
signal捕获信号
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handler(int sig)
{
if (SIGINT == sig)
printf("I got SIGINT signal!\n");
else if (SIGQUIT == sig)
printf("I got SIGQUIT signal!\n");
}
int main(int argc, char *argv[])
{
signal(SIGINT, handler);
signal(SIGQUIT, handler);
while (1)
{
printf("hello world!\n");
sleep(1);
}
return 0;
}
用父进程来捕获子进程的死亡状态信号:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
void handler(int sig)
{
wait(NULL);
printf("wait end!\n");
}
int main(int argc, char *argv[])
{
signal(SIGCHLD, handler);
pid_t pid;
if (0 > (pid = fork()))
{
perror("fork");
return -1;
}
else if (0 == pid)
{
sleep(3);
printf("Child exit!\n");
exit(0);
}
while (1)
{
printf("Parent!\n");
sleep(1);
}
return 0;
}