可以用kill(1)命令发送信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。
信号的产生1.通过终端按键产生信号
举个栗子:写一个死循环,前台运行这个程序,然后在终端键入Ctrl-c
当CPU正在执行这个进程的代码 , 终端驱动程序发送了一 个 SIGINT 信号给该进程,记录在该进程的 PCB中,则该进程的用户空间代码暂停执行 ,CPU从用户态 切换到内核态处理硬件中断。
从内核态回到用户态之前, 会先处理 PCB中记录的信号 ,发现有一个 SIGINT 信号待处理, 而这个信号的默认处理动作是终止进程,所以直接终止进程而不再返回它的用户空间代码执行。
2.调用系统函数向进程发信号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*************************************************************************
> File Name: test.c
> Author:Lynn-Zhang
> Mail: iynu17@yeah.net
> Created Time: Fri 15 Jul 2016 03:03:57 PM CST
************************************************************************/
#include<stdio.h>
int main()
{
printf("get pid :%d circle ...\n",getpid());
while(1);
return 0;
}
写一个上面的程序在后台执行死循环,并获取该进程的id,然后用kill命令给它发送SIGSEGV信号,可以使进程终止。也可以使用kill -11 5796,11是信号SIGSEGV的编号。
打开终端1,运行程序:
利用终端2,给进程发送信号
终端1 显示进程被core了:
kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定信号。raise函数可 以给当前进程发送指定的信号 (自己给自己发信号 )
1
2
3
#include<signal.h>
int kill(pid_t pid,int signo);
int raise(int signo);
这两个函数都是成功返回0,错误返回-1.
除此之外,abort函数使当前进程接收到SIGABRT信号而异常终止。
1
2
#include<stdlib.h>
void abort(void);
就像 exit函数一样 ,abort 函数总是会成功的 ,所以没有返回值。
3.由软件条件产生信号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*************************************************************************
> File Name: alarm.c
> Author:Lynn-Zhang
> Mail: iynu17@yeah.net
> Created Time: Fri 15 Jul 2016 08:52:02 PM CST
************************************************************************/
#include<stdio.h>
int main()
{
int count=0;
alarm(1);
while(1)
{
printf("%d\n",count);
count++;
}
return 0;
}
通过实现以上代码,调用alarm函数可以设定一个闹钟,告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。
该程序会在1秒钟之内不停地数数,并打印计数器,1秒钟到了就被SIGALRM信号终止。由于电脑配置等的不同,每台电脑一秒钟之内计数值是不同的一般是不同的。
1 2
#include <unistd.h> unsigned int alarm(unsigned int seconds);
alarm函数的返回值是0或上次设置闹钟剩余的时间。