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

来源:互联网 发布:淘宝永久不支持解绑 编辑:程序博客网 时间:2024/06/07 01:28

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:



原创粉丝点击