进程间通信系列 之 信号实例

 进程间通信系列 之 概述与对比  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\n");
    }

    int count=0;
    while(1){
        sleep(1);
        printf("wait for signal:%d\n",++count);
        if(count>10)break;
    }
    return 0;
}

void new_op(int signum,siginfo_t* info,void* myact){
    printf("receive signal:%d\n",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("\nhandle sig:%d\n",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\n");
    }

   // int count=0;
//    while(1){
//        sleep(1);
        printf("wait for sig\n");
        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\n");
    sleep(7);
    printf("Send dead\n");
    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\n");
    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\n",*p);
//        printf("%c,",(*((char*)((*info).si_ptr))));
    printf("op value:%d\n",info->si_int);
  //  }
}

int main(int argc,char** argv){
    int sig=atoi(argv[1]);
    pid_t pid=getpid();
    printf("Rev pid:%d\n",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\n");
    }

    int count=0;
    while(1){
        sleep(1);
        count++;
        printf("wait for sig %d\n",count);
        if(count>30)break;
    }
    return 0;
}


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


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用Linux进程间通信(IPC)机制的示例代码,包括使用管道(pipe)、共享内存(shared memory)和信号量(semaphore)进行进程间通信。 1. 使用管道(pipe)进行进程间通信: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define BUFFER_SIZE 25 int main() { int fd[2]; pid_t pid; char write_msg[BUFFER_SIZE] = "Greetings"; char read_msg[BUFFER_SIZE]; if (pipe(fd) == -1) { fprintf(stderr, "Pipe failed"); return 1; } pid = fork(); if (pid < 0) { fprintf(stderr, "Fork failed"); return 1; } if (pid > 0) // Parent process { close(fd[0]); write(fd[1], write_msg, BUFFER_SIZE); close(fd[1]); } else // Child process { close(fd[1]); read(fd[0], read_msg, BUFFER_SIZE); printf("Received message: %s\n", read_msg); close(fd[0]); } return 0; } ``` 2. 使用共享内存(shared memory)进行进程间通信: ``` #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHM_SIZE 1024 int main() { int shmid; key_t key = 1234; char *shm, *s; if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0) { perror("shmget"); exit(1); } if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } printf("Enter message: "); for (s = shm; (*s = getchar()) != '\n'; s++) ; *s = '\0'; printf("You entered: %s\n", shm); shmdt(shm); return 0; } ``` 3. 使用信号量(semaphore)进行进程间通信: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.h> #define MAX_RETRIES 10 union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main() { key_t key = 1234; int semid, semval; union semun arg; struct sembuf sembuf; if ((semid = semget(key, 1, IPC_CREAT | 0666)) == -1) { perror("semget"); exit(1); } arg.val = 1; if (semctl(semid, 0, SETVAL, arg) == -1) { perror("semctl"); exit(1); } if ((semval = semctl(semid, 0, GETVAL, 0)) == -1) { perror("semctl"); exit(1); } printf("Semaphore value before decrement: %d\n", semval); sembuf.sem_num = 0; sembuf.sem_op = -1; sembuf.sem_flg =

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoungerChina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值