zoukankan      html  css  js  c++  java
  • 《Linux应用进程间通信(五) — 信号》

    1.信号的概念

      信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动。通常信号是由一个错误产生的。但它们还可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程。一个信号的产生叫生成,接收到一个信号叫捕获。

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

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

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

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

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

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

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

    3.信号都有哪些

    kill  -l
    

      

    主要常用的几个信号有:

    SIGINT:ctrl+c 终止信号
    SIGQUIT:ctrl+ 终止信号
    SIGTSTP:ctrl+z 暂停信号
    SIGALRM:闹钟信号 收到此信号后定时结束,结束进程
    SIGCHLD:子进程状态改变,父进程收到信号
    SIGKILL:杀死信号
    

      

    4.相关函数

    4.1 kil函数

    #include <sys/types.h>
    #include <signal.h>
    
    int kill(pid_t pid, int sig);
    功能:给指定的进程发送任意信号

    参数:
      pid:指定的进程
      sig:要发送的信号

    返回值:
      成功:0; 失败:-1

      

    4.2 raise函数

    #include <signal.h>
    
    int raise(int sig);
    功能:进程向自己发送信号

    参数:
      sig:要发送的信号

    返回值:
      成功:0; 失败:-1

      

    4.3 alarm函数

    #include <unistd.h>
    
    unsigned int alarm(unsigned int seconds);
    功能:在金成功中设置一个定时器

    参数:
      seconds:定时时间,单位为秒

    返回值:
      如果调用此alarm()前,进程中已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。

      注意:一个进程只能有一个闹钟时间。如果在调用alarm时已设置过闹钟时间,则之前的闹钟时间被新值所代替。

    4.4 pause函数

    #include <unistd.h>
    
    int pause(void);
    功能:用于将调用进程挂起直到收到信号为止

      

    4.5 信号处理函数

    #include <signal.h>
    
    void (*signal(int signum, void (*handler)(int)))(int);
    或者 typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);
    参数:
      signum:要处理的信号//不能是SIGKILL和SIGSTOP
      handler:SIG_IGN:忽略该信号。
      SIG_DFL:采用系统默认方式处理信号。
      自定义的信号处理函数指针

    返回值:
      成功:设置之前的信号处理方式;失败:SIG_ERR

      

    4.6 abort函数

    #include <stdlib.h>
    
    void aabort(void);
    功能:给自己发送异常终止信号,(6.SIGABRO)终止并产生core文件。

      

    5.实例

    5.1 kill 函数发送杀死pid指向的进程的信号,raise 发送杀死自己的信号  

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <signal.h>
    #include <unistd.h>
    int main(int argc, const char *argv[])
    {
        pid_t pid;
        pid = fork();
        if(pid < 0)
        {
            perror("fork fail ");
            exit(1);
        }
        else if(pid == 0)
        {
            printf("child 
    ");
        }
        else
        {
            kill(pid,SIGKILL);//(此处pid是子进程的进程号)杀死 pid 发送进程的信号,kill 给其他进程发送信号,指定进程号
            printf("child killed
    ");
            sleep(1);
            printf("father 
    ");
            wait(NULL); //等待子进程结束,并回收子进程资源
            raise(SIGKILL); //杀死自己的信号,函数raise 给自己发送信号
        }
        return 0;
    }
    

      

       测试:子进程还未来得及运行就被杀死了

    5.2  定时器的使用

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(int argc, const char *argv[])
    {
        printf("%d
    ",alarm(7)); //7 秒定时器,此时返回 0 ,前面没有使用定时器
        sleep(2);  //睡 2 秒
        while(1)
        {
            printf("%d
    ",alarm(3)); //重新设置定时器值为 3 ,返回上次定时器剩余的时间,7-2 = 5
            sleep(7); //睡7秒,后会结束进程
        }
        return 0;
    }
    

      

       测试:Alarm clock 是定时器结束时提醒

    5.3  signal 信号使用例子

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    
    void handler(int arg)
    {
        printf("
    ctrl + c
    ");
    //    exit(1);
    //    raise(SIGKILL); 
        kill(getpid(),9); //9表示 SIGKILL 杀死信号
    }
    
    int main(int argc, const char *argv[])
    {
        signal(SIGINT,handler);//定义自己的处理信号,当SIGINT信号发生时,调用 handler 函数处理
        while(1);
        return 0;
    }
    

      

    5.4  signal 信号使用例子

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    int main(int argc, const char *argv[])
    {
        signal(SIGINT,SIG_IGN);// ctrl +c 信号被忽略,SIG_IGN 表示忽略该信号
        while(1);
    
        return 0;
    }
    

      

  • 相关阅读:
    找到排序矩阵中从小到大第K个数字
    使用VSCODE开发UE4
    UE4添加模块
    游戏串流
    DIY Arduino 方向盘
    免费/开源软件推荐
    把引擎插件变成工程插件
    MergeActors技巧
    烘焙卡在99%
    UMG里没有"Prefab"怎么办?
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/13154008.html
Copyright © 2011-2022 走看看