Linux C 进程间的IPC通信 之 共享内存(二)

1、父子进程(有亲缘关系)的IPC通信

                        int shmid;       shmid = shmget(IPC_PRIVATE, 128, IPC_CREAT | 0777); //创建共享内存,参数为 宏 IPC_PRIVATE

                        int pid;       char *p;     pid = fork();

                                        if(pid  > 0) { signal(SIGUSR2, myfun);      p = (char *)shmat(shmid, NULL, 0) ; ........kill(pid, SIGUSR1);......pause();.......}

                                                                   接收信号                                            映射 共享内存                               发送信号                    睡眠等待

                                        if(pid == 0) { signal(SIGUSR1,myfun);      p = (char *)shamt(shmid, NULL, 0); ...........pause();... ......... kill(pid,SIGUSR2);....... } 

2、无亲缘关系进程间的IPC通信

                     int key;         key = ftok("./a",'b'); //创建 共享内存的 key 值

                     int shmid;          shmid = shmget(key, 128, IPC_CREAT | 0777); //创建 共享内存

                   struct shmbuf *p;       p = (struct shmbuf *)shmat(shmid, NULL, 0); //映射 共享内存


代码 1  父子进程:

  1 #include <stdio.h>
  2 #include <sys/shm.h>
  3 #include <signal.h>
  4 
  5 void myfun(int sig)     //自定义信号处理方式
  6 {
  7         return; //唤醒
  8 }
  9 
 10 int main()
 11 {
 12         int shmid;
 13         char *p;
 14         int pid;
 15 
 16         shmid = shmget(IPC_PRIVATE, 128, IPC_CREAT | 0777);     //在内核空间创建 共享内存
 17         if(shmid < 0)
 18         {
 19                 printf("ERROR: share memory create failure.\n");
 20                 return -1;
 21         }
 22         printf("share memory shmid = %d\n", shmid);
 23 
 24         pid = fork();   //父子进程
 25         if(pid > 0)     //父进程
 26         {
 27 
 28                 signal(SIGUSR2, myfun); //接收处理 子进程发送的信号
 29                 p = (char *)shmat(shmid, NULL, 0);      //通知内核 将共享内存 映射到 用户空间的地址中
 30                 if(p == NULL)   //小心:不要写成 =,否则,编译器可以通过。执行时将出现 段错误
 31                 {
 32                         printf("ERROR: parent process shmat operation failure.\n");
 33                         return -2;
 34                 }
 35                 while(1)
 36                 {
 37                         printf("parent process pid = %d: write into share memory...\n",getpid());
 38                         fgets(p, 128, stdin);   //写入 共享内存
 39                         kill(pid,SIGUSR1);      //发送信号 给 子进程,将其唤醒 通知其可以读取
 40                         pause();        //睡眠,等待 子进程读取
 41                 }
 42         }
 43         if(pid == 0)    //子进程
 44         {
 45                 signal(SIGUSR1, myfun);
 46                 p = (char *)shmat(shmid, NULL, 0);      //通知内核 将共享内存 映射到 用户空间的地址中
 47                 if(p == NULL)
 48                 {
 49                         printf("ERROR: child process shmat operation failure.\n");
 50                         return -3;
 51                 }
 52                 while(1)
 53                 {
 54                         pause();        //睡眠,等待 父进程写入
 55                         printf("child process pid = %d read parent pid = %d: %s\n", getpid(), getppid(), p);    //读取 共享内存
 56                         kill(getppid(),SIGUSR2);        //发送信号 给 父进程,将其唤醒 通知其可以写入
 57                 }
 58         }
 59         shmdt(p);       //删除 用户空间中 共享内存的地址映射
 60         shmctl(shmid,IPC_RMID,NULL);    //删除 内核空间中 的共享内存
 61         system("ipcs -m");      //查看 共享内存
 62         return 0;
 63 }
执行1:


代码 2-1 进程server:

  1 #include <stdio.h>
  2 #include <sys/shm.h>
  3 #include <signal.h>
  4 
  5 struct shmbuf   //结构体
  6 {
  7         int pid;
  8         char buf[124];
  9 };
 10 
 11 void myfun(int sig)     //自定义信号处理方式
 12 {
 13         return; //唤醒
 14 }
 15 
 16 int main()
 17 {
 18         int shmid;
 19         int key;
 20         int pid;
 21         struct shmbuf *p;
 22 
 23         signal(SIGUSR2, myfun);         //接收信号,并处理
 24 
 25         key = ftok("./a",'b');  //创建共享内存的 key值
 26 
 27         shmid = shmget(key, 128, IPC_CREAT | 0777);     //创建 共享内存
 28 
 29         printf("server share memory shmid = %d, key = %X\n", shmid, key);
 30 
 31         p = (struct shmbuf *)shmat(shmid, NULL, 0);     //映射 共享内存
 32 
 33         p->pid = getpid();      //将自己的pid 写入 共享内存
 34         pause();        //睡眠,等待对方 读取 pid
 35         pid = p->pid;   //读取 对方写入的 pid
 36 
 37         while(1)
 38         {
 39                 printf("server write into share memory......\n");
 40                 fgets(p->buf, 124, stdin);      //写入 共享内存
 41                 kill(pid, SIGUSR1);     //发送信号,通知对方
 42                 pause();        //睡眠,等待
 43         }
 44         return 0;
 45 }


代码 2-2 进程 client::
  1 #include <stdio.h>
  2 #include <sys/shm.h>
  3 #include <signal.h>
  4 
  5 struct shmbuf   //结构体
  6 {
  7         int pid;
  8         char buf[124];
  9 };
 10 
 11 void myfun(int sig)     //自定义信号处理方式
 12 {
 13         return;
 14 }
 15 
 16 int main()
 17 {
 18         int key;
 19         int shmid;
 20         struct shmbuf *p;
 21         int pid;
 22 
 23         signal(SIGUSR1, myfun); //接受信号,并处理
 24         key = ftok("./a",'b');  //创建共享内存的key值
 25         if(key < 0)
 26         {
 27                 printf("ERROR: client process create key of shm failed.\n");
 28                 return -1;
 29         }
 30 
 31         shmid = shmget(key, 128, IPC_CREAT | 0777);     //创建共享内存
 32         if(shmid < 0)
 33         {
 34                 printf("ERROR: client process create share memory failed.\n");
 35                 return -2;
 36         }
 37         printf("share memory shmid = %d, key = %X\n", shmid, key);
 38 
 39         p = (struct shmbuf *)shmat(shmid, NULL, 0);     //将 内核中的 共享内存 映射到 用户空间的地址中
 40         if(p == NULL)
 41         {
 42                 printf("ERROR: client process shmat operation failure.\n");
 43                 return -3;
 44         }
 45         pid = p->pid;   //读取 server端 写入的 pid
 46         p->pid = getpid();      //写入自己的pid
 47         kill(pid, SIGUSR2);     //发送信号,通知server
 48         while(1)
 49         {
 50                 pause();        //睡眠,等待 server写入
 51                 printf("client read : %s\n", p->buf);   //读取 共享内存
 52                 kill(pid, SIGUSR2);     //发送信号,通知 server 读取完毕,可以 写入
 53         }
 54 
 55         shmdt(p);
 56         shmctl(shmid, IPC_RMID, NULL);
 57         system("ipcs -m");
 58 
 59         return 0;
 60 }

执行 2:



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值