一:通过终端按键产生信号
比如用户输入命令,在Shell下启动一个前台进程。
- 用户按Ctrl + C,这时在键盘产生一个硬件中断,被操作系统获取,解释成信号,发送给目标前台进程,前台进程因为收到信号,进而引起进程退出。
二:调用系统函数向进程发信号
(1):kill()函数 int kill(pid_t pid, int sig); kill函数可以给一个指定的进程发送指定的信号。
(2):raise()函数 int raise(int sig); raise函数可以给当前进程发送指定的信号(自己给自己发信号)。
这两个函数都是成功返回0,错误返回-1;
(3):abort()函数 void abort(void); abort函数使当前进程接收到信号而异常终止。
就像exit函数一样,abort函数总是会成功的,所以没有返回值。
三:由软件条件产生信号
这里主要介绍一个alarm函数和SIGALRM信号;
unsigned int alarm(unsigned int seconds); 调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒后给当前进程发送SIGALRM信号,该信号的默认处理动作是终止当前进程。
这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。
int main()
{
int count = 0;
alarm(1);
for(;1;count++)
{
printf("count = %d\n", count);
}
return 0;
}
四:硬件异常产生信号
硬件异常被硬件以某种方式被硬件检测到并通知内核然后内核向当前进程发送适当的信号。例如当前进程执行了除以O的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
总结
- 上面所说的信号的产生,最终都是要操作系统来执行,因为OS是进程的管理者。
- 信号的处理是在合适的时候处理的!(下篇博客详细讲)
- 信号如果不是被立即处理的,需要记录在进程控制块中。
|