一.概述
信号可以用来向进程传递消息,当操作系统不想让某个进程运行的时候,会给这个进程发送相应的结束信号。man page的第七章专门来讲Signal, 可以通过man 7 signal 指令来查看。
信号可以由以下途径产生:
1) 终端特殊按键
Ctrl+c SIGINT
Ctrl+z SIGTSTP
Ctrl+\ SIGQUIT
2) 硬件异常
* 除0操作
* 访问非法内存
3) 某些特殊函数
kill()&raise()&abort()&alarm()
二.kill()函数
kill() 函数可以向指定的进程发送指定的信号
int kill(pid_t pid, int sig) pid > 0 sig发送给ID为pid的进程 pid == 0 sig发送给与发送进程同组的所有进程 pid < 0 sig发送给组ID为|-pid|的进程,并且发送进程具有向其发送信号的权限 pid == -1 sig发送给发送进程有权限向他们发送信号的系统上的所有进程 sig为0时,用于检测,特定为pid进程是否存在,如不存在,返回-1。
例:向某个进程发送指定的信号
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <signal.h> int main(int argc, char *argv[]) { if (argc < 3) { printf("Invalid arguments\n"); exit(1); } if (kill((pid_t)atoi(argv[1]), atoi(argv[2])) < 0) { perror("kill"); exit(2); } return 0; }
运行:
结束掉5297这个进程组
./kill -5297 9
注意:
普通用户只能向自己创建的进程发信号,无法向root用户或其它用户生成的进程发信号。
三.raise()函数
raise()函数可以向自己发送指定的信号
#include <signal.h> int raise(int sig);
例:
#include <stdio.h> #include <stdlib.h> #include <signal.h> int main() { printf("This is a new question\n"); printf("This is a dog\n"); printf("This is a cat\n"); raise(9); return 0; }
四.abort()函数
abort()函数相当于调用进程向自己发送了一个SIGABRT(6)的信号
#include <stdlib.h>
void abort(void);
例:
#include <stdio.h> #include <stdlib.h> int main() { printf("This is new question -------------1\n"); printf("This is new question -------------2\n"); printf("This is new question -------------3\n"); printf("This is new question -------------4\n"); sleep(5); abort(); return 0; }
五.alarm()函数
操作系统在管理进程的时候,会为每个进程都分配一个定时器(闹钟)——alarm, 而alarm()函数可以指定定时的秒数,当指定的秒数到达后,会向当前进程发送一个SIGALRM的信号,该信号的默认处理动作是终止当前进程。
#include <unistd.h> unsigned int alarm(unsigned int seconds);
例:
#include <stdio.h> #include <unistd.h> int main() { int i = 0; alarm(5); while(1) { printf("current i is: %d\n", i); i++; } return 0; }
运行, 5秒后会给该进程发送一个SIGALRM信号,终止当前进程。
注意:
alarm()函数仅仅是设定定时器的秒数,并不会导致进程阻塞。