zoukankan      html  css  js  c++  java
  • 进程间通信系列 之 信号实例

     进程间通信系列 之 概述与对比  http://blog.csdn.net/younger_china/article/details/15808685
     进程间通信系列 之 共享内存及其实例   http://blog.csdn.net/younger_china/article/details/15961557
     进程间通信系列 之 共享内存简单实例   http://blog.csdn.net/younger_china/article/details/15991081
     进程间通信系列 之 信号(理论)   http://blog.csdn.net/younger_china/article/details/15976961
     进程间通信系列 之 信号实例   http://blog.csdn.net/younger_china/article/details/15968715
     进程间通信系列 之 信号综合实例   http://blog.csdn.net/younger_china/article/details/15980485
     进程间通信系列 之 命名管道FIFO及其应用实例   http://blog.csdn.net/younger_china/article/details/15808531
     进程间通信系列 之 管道(客户端和服务端通信)   http://blog.csdn.net/younger_china/article/details/15809281
     进程间通信系列 之 信号量详解及编程实例   http://blog.csdn.net/younger_china/article/details/15808531
     进程间通信系列 之 消息队列函数及其范例   http://blog.csdn.net/younger_china/article/details/15503871
     进程间通信系列 之 消息队列应用实例   http://blog.csdn.net/younger_china/article/details/15808501 
     进程间通信系列 之 socket套接字及其实例  
    http://blog.csdn.net/younger_china/article/details/15809163
     进程间通信系列 之 socket套接字实例   http://blog.csdn.net/younger_china/article/details/15809207


    信号

    信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。

    信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。

    进程可以通过三种方式来响应一个信号:

    (1)忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL及 SIGSTOP;

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

    (3)执行缺省操作;


     

    信号发送及处理

    sigreceive.c

    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    void new_op(int,siginfo_t*,void*);
    int main(int argc,char**argv){
        struct sigaction act;
        int sig=atoi(argv[1]);
    
        sigemptyset(&act.sa_mask);
        act.sa_flags=SA_SIGINFO;
        act.sa_sigaction=new_op;
    
        if(sigaction(sig,&act,NULL)<0){
            printf("install signal error
    ");
        }
    
        int count=0;
        while(1){
            sleep(1);
            printf("wait for signal:%d
    ",++count);
            if(count>10)break;
        }
        return 0;
    }
    
    void new_op(int signum,siginfo_t* info,void* myact){
        printf("receive signal:%d
    ",signum);
        sleep(5);
    }


    后台运行 sigreceive signo &,可获得该进程的 ID,假设为 pid,然后再另一终端上运行 kill -s signo pid 验证信号的发送接收及处理.

    信号传递附加信息

    1.向进程本身发送信号,并传递指针参数

    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    void new_op(int sig,siginfo_t* info,void* act){
        int i=0;
        for(i=0;i<10;i++){
            printf("%c,",(*((char*)((*info).si_ptr)++)));
        }
        printf("
    handle sig:%d
    ",sig);
    }
    
    int main(int argc,char** argv){
        struct sigaction act;
        union sigval mysigval;
        int i;
        int sig;
        pid_t pid=getpid();
        char data[10]={'2','2','2','2','2'};
        mysigval.sival_ptr=data;
        sig=atoi(argv[1]);
    
        sigemptyset(&act.sa_mask);
        act.sa_sigaction=new_op;
        act.sa_flags=SA_SIGINFO;
    
        if(sigaction(sig,&act,NULL)<0){
            printf("install sig error
    ");
        }
    
       // int count=0;
    //    while(1){
    //        sleep(1);
            printf("wait for sig
    ");
            sigqueue(pid,sig,mysigval);
        //    if(count++>10)break;
      //  }
        return 0;
    }

    2、 不同进程间传递整型参数:把 1 中的信号发送和接收放在两个程序中,并且在发送过程中传递整型参

    sig_send.c

    #include <unistd.h>
    #include <sys/types.h>
    #include <signal.h>
    
    int main(int argc,char** argv){
        union sigval sigv;
       // char** data={"First","Second"};
    //    char** data = (char**)malloc(sizeof(char* )*2);
      //  data[0] = "first";
       // data[1] ="second";
    
    //    char* data[2]={"First","Second"};
    //    sigv.sival_ptr=data;
    
        char data[2]={'1','1'};
    //    sigv.sival_ptr=data;
        sigv.sival_int=9;
    
        pid_t pid=atoi(argv[1]);
        int sig=atoi(argv[2]);
        
        sigqueue(pid,sig,sigv);
        printf("Message has been send
    ");
        sleep(7);
        printf("Send dead
    ");
        return 0;
    }


    sig_rev.c

    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    void op(int sig,siginfo_t *info,void* sigact){
        printf("inside op
    ");
        int count=0;
    //    while((*info).si_ptr!=NULL){
            count++;
           // char* p=*((char**)((*info).si_ptr)+1);
           // char* p=((char*)((*info).si_ptr));
           // printf("op %c
    ",*p);
    //        printf("%c,",(*((char*)((*info).si_ptr))));
        printf("op value:%d
    ",info->si_int);
      //  }
    }
    
    int main(int argc,char** argv){
        int sig=atoi(argv[1]);
        pid_t pid=getpid();
        printf("Rev pid:%d
    ",pid);
    
        struct sigaction act;
        sigemptyset(&act.sa_mask);
        act.sa_flags=SA_SIGINFO;
        act.sa_sigaction=op;
    
        if(sigaction(sig,&act,NULL)<0){
            printf("install sig error
    ");
        }
    
        int count=0;
        while(1){
            sleep(1);
            count++;
            printf("wait for sig %d
    ",count);
            if(count>30)break;
        }
        return 0;
    }


    注:实例 2 的两个例子侧重点在于用信号来传递信息,目前关于在 linux 下通过信号传递信息的实例非常
    少,倒是 Unix 下有一些,但传递的基本上都是关于传递一个整数,传递指针的我还没看到。我一直没有实
    现不同进程间的指针传递(实际上更有意义),也许在实现方法上存在问题吧

    
  • 相关阅读:
    Docker02 Docker初识:第一个Docker容器和Docker镜像
    Docker01 CentOS配置Docker
    Jenkins02:Jenkins+maven+svn集成
    Junit01 新建Maven项目
    Junit02 Junit创建及简单实现
    Jenkins01:linux+jenkins+ant+jmeter集成
    Jenkins初识03:构建定时任务
    python 协程
    python之socket 网络编程
    python 面向对象
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624524.html
Copyright © 2011-2022 走看看