发送信号
由用户发送的信号
在进程里向其他进程发送信号:
int kill(pid_t pid, int sig);
函数功能:向指定进程或进程组发送信号
参数:pid
pid > 0 将信号发送给进程id等于pid的那个进程;
pid == 0 将信号发送给当前进程同组的进程,包括当前进程自己;
pid == -1 如果当前进程拥有发送信号的权限,就把信号发送给除init进程外的所有进程;
pid < -1 将信号发送给进程组号为pid绝对值(-pid)里的所有进程;
参数:sig 要发送的信号;
返回值:成功返回0;失败返回-1并置错误码。
在终端向某个进程发送信号:
通过kill向进程id发送信号:
kill -SIGKILL pid 或 kill -KILL pid 或 kill -9 pid
通过killall向进程名发送信号:
killall -SIGKILL a.out 或 killall -KILL a.out 或 killall -9 a.out
内核发送信号
①当子进程退出自动发送SIGCHLD给父进程;
②按下CTRL+C组合键,内核发送SIGINT给当前执行的进程;
③当程序访问非法内存,产生段错误,内核发送SIGSEGV给进程。
…
信号值
捕捉信号
typedef void (*sighandler_t)(int); //信号响应函数指针
sighandler_t signal(int signum, sighandler_t handler); //捕捉信号函数
函数功能:捕捉一个其他进程发送到当前进程的信号,为某个信号的到来做好“预先”措施
参数signum: 捕捉到的信号值
参数handle:捕捉到信号后,用handle函数指针指向的函数来做响应
返回值:失败返回SIG_ERR并置错误码;成功返回上一次调用此函数的handle指针。
signal函数特点:
①捕捉到信号后,不会取执行该信号的默认动作,而是取执行新信号响应函数;
②在调用signal函数时,程序不会阻塞,会继续往下执行,这个捕捉信号函数是全局有效的,在程序执行的任意时刻都可以捕获信号;
③SIGKILL和SIGSTOP信号不能被捕获,只能执行信号的默认动作;
④signal函数会将捕获到的信号当做实参传递给handle函数。
子进程发送自定义信号SIGUSR1给父进程
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
void signal_handle(int arg) //arg为signal捕捉到的信号值
{
switch(arg)
{
case SIGUSR1:
printf("SIGUSR1[%d] is caught\n", SIGUSR1);
break;
default:
printf("other signal is caught\n");
break;
}
}
int main(int argc, char const *argv[])
{
pid_t id;
//父进程捕捉信号
if(SIG_ERR == signal(SIGUSR1, signal_handle)) //捕捉信号函数是全局有效的
{
perror("signal");
exit(1);
}
id = fork();
if(id > 0)
wait(NULL); //父进程阻塞等待子进程终止
else if(0 == id)
{
if(-1 == kill(getppid(), SIGUSR1)) //向父进程发送自定义信号SIGUSR1
printf("signal send failed\n"); //kill发送信号失败返回-1
else
{
printf("signal send succeed\n");
exit(2);
}
}
else
perror("fork");
return 0;
}