[转自: http://blog.csdn.net/Paradise_for_why/article/details/5550619]

这一章就是著名的IPC,这个东西实际的作用和它的名字一样普及。例如我们浏览网页,打印文章,等等。

    IPC总共有五种类型:

  1. 共享内存(Shared Memory):最容易理解的一种,就像一个特工把情报放在特定地点(内存),另一个特工再过来取走一样。

  2. 内存映射(Mapped Memory):和共享内存几乎相同,除了特工们把地点从内存改成了文件系统。

  3. 管道(Pipes):从一个进程到另一个进程的有序通信,用电话来比喻再恰当不过了。

  4. FIFOs:和管道和类似,唯一的区别是FIFOs比管道更神通一些,允许没有关系的进程之间的有序通信。

  5. 套接字(Sockets):为什么说浏览网页也是IPC?就是因为它。 

  • 共享内存是最快捷的进程间通信方式。访问共享内存的效率和访问进程自己的非共享内存的效率是相同的,而且这种通信方式不需要任何额外的系统调用。
  • 系统不会自动为共享内存处理同步问题,这个问题必须由用户自己解决。
  • 共享内存的步骤通常是:
    • 一个进程申请一块共享内存,即在它的页表中加入新的一项
    • 所有进程Attach该共享内存,即从申请内存的进程中拷贝对应的页表
    • 使用该内存进行通讯
    • 结束后所有进程detach该共享内存
    • 申请共享内存的进程在确定所有进程都detach后,释放该内存
  • 由于共享内存是通过页表来实现的,我们可以得出一个结论:共享内存的大小是页面大小的整数倍,页面的大小可以通过getpagesize()来得到,通常在Linux下该值是4KB
  • 相关的API函数:
    • 申请共享内存:shmget,返回共享内存segment的id
    • Attach,Detach函数:shmat,shmdt。需要共享内存segment的id
    • 释放申请的内存:shmctl。一定要记得释放!调用exit和exec会自动detach,但不会自动释放。
  • 使用 ipcs -m来观看当前系统存在的共享内存

  例子:原程序链接,依据这个例子进行简单修改一下

 

  1 /*
  2  * =============================================================================
  3  *
  4  *       Filename:  sharememory_read.c
  5  *
  6  *    Description:  
  7  *
  8  *        Version:  1.0
  9  *        Created:  2014年11月04日 19时52分28秒
 10  *       Revision:  none
 11  *       Compiler:  gcc
 12  *
 13  *         Author:  lwq (28120), scue@vip.qq.com
 14  *   Organization:  
 15  *
 16  * =============================================================================
 17  */
 18 #include <stdlib.h>
 19 
 20 /**********************************************************
 21 *实验要求:   创建两个进程,通过共享内存进行通讯。
 22 *功能描述:   本程序申请和分配共享内存,然后轮训并读取共享中的数据,直至
 23 *           读到“end”。
 24 *日    期:   2010-9-17
 25 *作    者:   国嵌
 26 **********************************************************/
 27 #include <unistd.h>
 28 #include <stdlib.h>
 29 #include <stdio.h>
 30 #include <string.h>
 31 #include <sys/types.h>
 32 #include <sys/ipc.h>
 33 #include <sys/shm.h>
 34 #include <getopt.h>
 35 #include "sharememory.h"
 36 
 37 void read_shm(struct shared_use_st *shared_stuff);
 38 void write_shm(struct shared_use_st *shared_stuff);
 39 void del_shm();
 40 
 41 void usage(){
 42     fprintf(stderr, "\nusage: %s -r|-w\n\n"
 43             "-r read mode\n"
 44             "-w write mode\n"
 45             "\n", "shared_memory");
 46     exit(1);
 47 }
 48 
 49 #define READ (1)
 50 #define WRITE (2)
 51 #define OPTNONE (0)
 52 
 53 // 全局变量
 54 void *shared_memory=(void *)0;
 55 
 56 /*
 57  * 程序入口
 58  * */
 59 int main(int argc, char **argv)
 60 {
 61     int running=RUNNING;
 62     struct shared_use_st *shared_stuff;
 63     int shmid;
 64     int operation=OPTNONE;                      /* 读/写操作 */
 65 
 66     /*-----------------------------------------------------------------------------
 67      *  getopt start
 68      *----------------------------------------------------------------------------*/
 69     int choice;
 70     while (1)
 71     {
 72         static struct option long_options[] =
 73         {
 74             /* Use flags like so:
 75             {"verbose",    no_argument,    &verbose_flag, 'V'}*/
 76             /* Argument styles: no_argument, required_argument, optional_argument */
 77             {"version", no_argument,    0,    'v'},
 78             {"help",    no_argument,    0,    'h'},
 79             {"read",    no_argument,    0,  'r'},
 80             {"write",   no_argument,    0,  'w'},
 81             {0,0,0,0}
 82         };
 83     
 84         int option_index = 0;
 85     
 86         /* Argument parameters:
 87             no_argument: " "
 88             required_argument: ":"
 89             optional_argument: "::" */
 90     
 91         choice = getopt_long( argc, argv, "vhrw",
 92                     long_options, &option_index);
 93     
 94         if (choice == -1)
 95             break;
 96     
 97         switch( choice )
 98         {
 99             case 'v':
100                 
101                 break;
102     
103             case 'h':
104                 usage();
105                 break;
106 
107             case 'r':
108                 operation=READ;
109                 break;
110 
111             case 'w':
112                 operation=WRITE;
113                 break;
114     
115             case '?':
116                 /* getopt_long will have already printed an error */
117                 usage();
118                 break;
119     
120             default:
121                 /* Not sure how to get here... */
122                 return EXIT_FAILURE;
123         }
124     }
125     if (operation == OPTNONE) {
126         usage();
127     }
128     /*-----------------------------------------------------------------------------
129      *  getopt end
130      *----------------------------------------------------------------------------*/
131 
132     /*创建共享内存*/
133     shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
134     if(shmid==-1) {
135         fprintf(stderr,"shmget failed\n");
136         exit(EXIT_FAILURE);
137     }
138 
139     /*映射共享内存*/
140     shared_memory=shmat(shmid,(void *)0,0);
141     if(shared_memory==(void *)-1) {
142         fprintf(stderr,"shmat failed\n");
143         exit(EXIT_FAILURE);
144     }
145 
146     printf("Memory attached at 0%08x\n",(int)((intptr_t)shared_memory));
147 
148     /*让结构体指针指向这块共享内存*/
149     shared_stuff=(struct shared_use_st *)shared_memory;
150 
151     /*控制读写顺序*/
152     // lwq: 使之能读取上一条消息
153     if (operation == READ && shared_stuff->written_by_you != HADWROTE)
154         shared_stuff->written_by_you=HADREAD;
155 
156     switch(operation) {
157         case READ:
158             read_shm(shared_stuff);
159             break;
160     
161         case WRITE:
162             write_shm(shared_stuff);
163             break;
164 
165         default:
166             usage();
167             break;
168     }
169 
170     del_shm();
171     exit(EXIT_SUCCESS);
172 }
173 
174 // 读取共享内存
175 void read_shm(struct shared_use_st *shared_stuff){
176     while(1) {
177        if(shared_stuff->written_by_you == HADWROTE) {
178            printf("You wrote:%s",shared_stuff->some_text);
179            shared_stuff->written_by_you=HADREAD;
180            if(strncmp(shared_stuff->some_text,"end",3)==0) {
181                break;
182            }
183        }
184        else {
185            usleep(100000);
186        }
187     }
188 }
189 
190 // 写入共享内存
191 void write_shm(struct shared_use_st *shared_stuff){
192     char buffer[BUFSIZ] = {0};
193     while(1) {
194         while(shared_stuff->written_by_you!=HADREAD); /* 等待读写完成 */
195         printf("Enter some text:");
196         fgets(buffer,BUFSIZ,stdin);
197         strncpy(shared_stuff->some_text,buffer,TEXT_SZ); /* 复制进去 */
198         shared_stuff->written_by_you=HADWROTE;
199         if(strncmp(buffer,"end",3)==0) {
200             break;
201         }
202     }
203 }
204 
205 // 删除共享内存
206 void del_shm(){
207     /*删除共享内存*/
208     if(shmdt(shared_memory)==-1) {
209         fprintf(stderr,"\nshmdt failed\n");
210         exit(EXIT_FAILURE);
211     }
212     else {
213         fprintf(stderr, "\ndelete shared_memory: 0x%08x\n", (int)((intptr_t)shared_memory));
214     }
215 }
sharememory.c

相关文章:

  • 2021-06-28
  • 2022-12-23
  • 2022-01-07
  • 2022-12-23
  • 2021-10-20
  • 2021-11-12
  • 2022-01-06
猜你喜欢
  • 2021-09-24
  • 2021-05-27
  • 2021-05-26
  • 2022-12-23
  • 2022-12-23
  • 2021-10-13
相关资源
相似解决方案