信号

1. 信号通信

1) 信号是一种异步通信方式,是软件层次上对中断机制的一种模拟。

2) 信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。

3) 如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复再执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。

 

2. 用户进程对信号的相应方式

忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。

捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。

执行缺省操作: Linux对每种信号都规定了默认操作。

 

3. 使用信号的场合

1)后台进程需要使用信号,如xinetd(管理网络服务)。

2)如果两个进程没有亲缘关系,无法使用无名管道

3)如果两个通信进程之一只能使用标准输入和标准输出,则无法使用FIFO

 

4. 常见的信号与缺省动作

 

信号

 

5. 信号发送与捕捉函数kill()和raise()

1)信号发送

函数kill()

头文件:#include

              #include

函数原型:int kill(pid_t pid, int sig)

函数参数:

              pid:

                     正数       发送信号给进程标识符为pid的进程

                     0            信号被发送到所有和当前进程在同一个进程组的进程

                     -1          信号被发送给所有的有权给其发送信号的进程(除了1号init进程)

                    

              sig   需要发送的信号。若为0则不会送出信号,但是系统会执行错误检查。通常用0来检测某个进程是否正在运行

函数返回值:

              成功:0

              失败:-1

             

2)信号发送

函数raise()(注:该函数允许进程向自己发送信号,等价于kill(getpid(),sig)或pthread_kill(pthread_self(),sig))

头文件:#include

函数原型:int raise(int sig)

函数参数:

              sig   需要发送的信号。若为0则不会送出信号,但是系统会执行错误检查。通常使用0来检测某个进程是否正在运行

函数返回值:

              成功:0

              失败:-1

 

示例代码:

/*************************************************************************

 @Author: wanghao

 @Created Time : Wed 23 May 2018 08:31:31 PMPDT

 @File Name: signal.c

 @Description:

 ************************************************************************/

#include

#include

#include

#include

 

int main(int argc, const char *argv[])

{

       pid_tpid;

      

       if((pid= fork())

       {

              perror(“”);

              exit(1);

       }

 

       if(pid== 0)

       {

              //raise(SIGSTOP);

              printf(“childprocess exit…n”);

              exit(0);

       }

       else

       {

              printf(“pid= %dn”,pid);

              sleep(1);

              if(waitpid(pid,NULL, WNOHANG))

              {

                     kill(pid,SIGKILL);

                     printf(“kill= %dn”,pid);

              }

       }

 

       return0;

}

 

运行结果:

pid = 3417

child process exit…

kill = 3417

 

6. 信号发送与捕捉函数alarm()与pause()

alarm()函数也称为闹钟函数,它可以在进程中设定一个定时器,当定时器计时结束时,它就会向进程发送SIGALRM信号,并且在终端输出”Alarm clock”表示计时结束。

pause()函数用于将该进程挂起直至接收到某个信号为止。

 

1)  函数alarm()

头文件:#include

函数原型:unsigned int alarm(unsigned intsecond)

函数参数:

              second   指定倒计时秒数,在second秒后发送SIGALRM信号

       函数返回值:

              成功:如果在调用alarm前已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间(注意是上一个闹钟时间不是本次alarm),如果以前没有设置国闹钟返回0.

              失败:-1

             

2) 函数pause()

头文件:#include

函数原型:int pause()

函数参数:无

函数返回值:-1,并且把errno设定为EINTR(仅会在接收到信号后返回)

 

示例:调用alarm()函数设置闹钟,pause()函数暂停本进程,直到本进程收到闹钟信号,

唤醒本进程。

示例代码:

/*************************************************************************

 @Author: wanghao

 @Created Time : Wed 23 May 2018 10:49:24 PMPDT

 @File Name: alarm.c

 @Description:

 ************************************************************************/

#include

#include

 

int main(int argc, const char *argv[])

{

       intret;

 

       ret= alarm(5);

 

       pause();

       printf(“Ihave been waken up.n”);

 

       return0;

}

 

7. 信号的处理

1)特定的信号是与相应的事件相联系的。

2)一个进程可以设定对信号的相应方式。

3)信号处理的主要方法有两种

       使用简单的signal()函数

       使用信号集函数族

4)使用signal()函数处理时,需指定要处理的信号和处理函数

 

8.信号处理函数   

函数signal()

头文件:#include

函数原型:

              typedefvoid (*sighandler_t)(int);

              sighandler_tsignal(int signum, sighandler_t handler);

函数参数:

              signum   指定信号

              handler  指定接收信号后的处理方式

              SIG_IGN:忽略信号

              SIG_DFL:采用默认方式处理信号

              其他:自定义信号处理函数

函数返回值:

              成功:以前的信号处理函数

              失败:SIG_ERR

 

示例: 将信号SIGINT和SIGQUIT的默认操作改为自定义操作。(注: 不能更改SIGKILL及SIGSTOP默认操作)

示例代码:

/*************************************************************************

 @Author: wanghao

 @Created Time : Wed 23 May 2018 11:12:56 PMPDT

 @File Name: signal_handle.c

 @Description:

 ************************************************************************/

#include

#include

 

void my_func(int sign_no);

 

int main(int argc, const char *argv[])

{

       printf(“Changesignal SIGINT and SIGQUIT function!n”);

       signal(SIGINT,my_func);

       signal(SIGQUIT,my_func);

 

       while(1)

       {

              sleep(1);

       }

       return0;

}

 

void my_func(int sign_no)

{

       if(sign_no== SIGINT)

       {

              printf(“Igot SIGINTn”);

       }

       elseif(sign_no == SIGQUIT)

       {

              printf(“Igot SIGQUITn”);

       }

}

运行该程序,在另一个窗口输入:

kill -2 3664

kill -3 3664

kill -9 3664

 

结果如下:

Change signal SIGINT and SIGQUIT function!

I got SIGINT

I got SIGQUIT

Killed

 

来源:朝辞暮见

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年4月21日
下一篇 2018年4月21日

相关推荐