关于 Linux 信号详解(2)

     可以用kill(1)命令发送信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。

 信号的产生

1.通过终端按键产生信号

举个栗子:写一个死循环,前台运行这个程序,然后在终端键入Ctrl-c

关于 Linux 信号详解

  当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,运行程序:

关于 Linux 信号详解

 利用终端2,给进程发送信号

关于 Linux 信号详解

 终端1 显示进程被core了:

关于 Linux 信号详解

关于 Linux 信号详解

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或上次设置闹钟剩余的时间。

关于 Linux 信号详解

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/15064.html