6、linux进程间通信之信号通信

来源:互联网 发布:航空霸业2飞机数据 编辑:程序博客网 时间:2024/05/29 05:05
 

       信号通信

     信号(signal)机制是unix系统中最为古老的进程间通信机制,很多条件可以产生一个信号。

²        当用户按下某些按键时,产生信号。

²        硬件异常产生信号:除数为0,无效的存储访问等等。这些情况通常由硬件检测到,将其通知内核,然后内核产生适当的信号通知进程。例如,内核对正在访问一个无效的存储区的进程产生一个SIGSEGV信号。

²        进程用kill函数将信号发送给另一个进程

²        用户可以用kill命令将信号发送给其他进程

                     信号处理:

Ø         忽略此信号

大多数信号都是按这种方式处理。但是SIGKILL和SIGSTOP不能被忽略,        因为它们是向超级用户提供了一种终止或停止进程的方法

Ø         执行用户希望的动作

Ø         执行系统默认动作

大多数信号的系统默认动作是终止该进程

 

 

发送信号

主要函数有:kill 与raise

区别:

Kill既可以向自己发送信号,也可以向其他进程发送信号。Raise函数是向进程自身发送信号。

#include<sys/types.h>

#include<signal.h>

int kill (pid_t pid ,int signo)

int raise(int signo)

 

kill的pid参数有四种不同的情况

A.        Pid>0 将信号发送给进程ID为pid的进程

B.        Pid=0 将信号发送给同组的进程

C.        Pid<0 将信号发送给其进程组ID等于pid绝对值的进程

D.       Pid=-1 将信号发送给所有进程。

 

alarm

使用alarm函数可以设置一个时间值(闹钟时间),当所设置的时间到了时,产生SIGALRM信号。如果不捕捉此信号,则默认动作是终止该进程。

#include<unistd.h>

Unsigned int alarm(unsigned int seconds)

Seconds:经过了指定的seconds秒后会产生信号SIGALRM.

 

 

 

Pause

Pause函数使调用进程挂起直至捕捉到一个信号。

#include<unistd.h>

int pause(void)

只有执行了一个信号处理函数后,挂起才结束。

 

 

Signal

#include<signal.h>

Void   (*signal(int signo,  void (*fun)(int)  ) )    (int)

                          如何理解????

                       //函数指针包含一个函数指针返回函数指针

Typedef void (*sighandler_t)(int)      //(*sighandler_t)(int)为void

Sighandler_t signal(int signum,sighandler_t handler)

 

Func可能值是:

l         SIG_IGN 忽略此信号

l         SIG_DFL 按系统默认的方式处理

l         信号处理函数名、: 使用该函数处理

 

 

例题:mysignal.c

        #include <signal.h>

        #include <stdio.h>

        #include <stdlib.h>

        void my_func(int sign_no)

        {

        if(sign_no==SIGINT)

        printf("I have get SIGINT\n");

            else if(sign_no==SIGQUIT)

        printf("I have get SIGQUIT\n");

        }

        int main()

        {

            printf("Waiting for signal SIGINT or SIGQUIT \n ");

        /*注册信号处理函数*/

        signal (SIGINT, my_func);

        signal(SIGQUIT, my_func);

        pause();                                    //等待信号

        exit(0);                                    //安全退出

    }

       

       

 

         如何测试?????

        1)./mysignal

            Waiting for signal SIGINT or SIGQUIT

       2)man kill

 

     3) ps aux

   

 

      4) kill –s SIGQUIT  9988

   

 

  然后: