1 /*共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间)
  2   从而使得这些进程可以相互通信。
  3   在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共享内存应用编程接口API允许一个进程使
  4   用公共内存区段。但是对内存的共享访问其复杂度也相应增加。共享内存的优点是简易性。
  5   使用消息队列时,一个进程要向队列中写入消息,这要引起从用户地址空间向内核地址空间的一次复制,
  6   同样一个进程进行消息读取时也要进行一次复制。共享内存的优点是完全省去了这些操作。
  7   共享内存会映射到进程的虚拟地址空间,进程对其可以直接访问,避免了数据的复制过程。
  8   因此,共享内存是GNU/Linux现在可用的最快速的IPC机制。
  9   进程退出时会自动和已经挂接的共享内存区段分离,但是仍建议当进程不再使用共享区段时
 10   调用shmdt来卸载区段。
 11   注意,当一个进程分支出父进程和子进程时,父进程先前创建的所有共享内存区段都会被子进程继承。
 12   如果区段已经做了删除标记(在前面以IPC——RMID指令调用shmctl),而当前挂接数已经变为0,
 13   这个区段就会被移除。
 14  */
 15 /*
 16   shmget(  )  创建一个新的共享内存区段
 17               取得一个共享内存区段的描述符
 18   shmctl(  )  取得一个共享内存区段的信息
 19               为一个共享内存区段设置特定的信息
 20               移除一个共享内存区段
 21   shmat(  )   挂接一个共享内存区段
 22   shmdt(  )   于一个共享内存区段的分离
 23  */
 24 //创建一个共享内存区段,并显示其相关信息,然后删除该内存共享区
 25 #include <stdio.h>
 26 #include <unistd.h>  //getpagesize(  )
 27 #include <sys/ipc.h>
 28 #include <sys/shm.h>
 29 #define MY_SHM_ID 67483
 30 int main(  )
 31     {
 32         //获得系统中页面的大小
 33         printf( "page size=%d/n",getpagesize(  ) );
 34         //创建一个共享内存区段
 35         int shmid,ret;
 36         shmid=shmget( MY_SHM_ID,4096,0666|IPC_CREAT );
 37         //创建了一个4KB大小共享内存区段。指定的大小必须是当前系统架构
 38         //中页面大小的整数倍
 39         if( shmid>0 )
 40             printf( "Create a shared memory segment %d/n",shmid );
 41         //获得一个内存区段的信息
 42         struct shmid_ds shmds;
 43         //shmid=shmget( MY_SHM_ID,0,0 );//示例怎样获得一个共享内存的标识符
 44         ret=shmctl( shmid,IPC_STAT,&shmds );
 45         if( ret==0 )
 46             {
 47                 printf( "Size of memory segment is %d/n",shmds.shm_segsz );
 48                 printf( "Numbre of attaches %d/n",( int )shmds.shm_nattch );
 49             }
 50         else
 51             {
 52                 printf( "shmctl(  ) call failed/n" );
 53             }
 54         //删除该共享内存区
 55         ret=shmctl( shmid,IPC_RMID,0 );
 56         if( ret==0 )
 57             printf( "Shared memory removed /n" );
 58         else
 59             printf( "Shared memory remove failed /n" );
 60         return 0;
 61     }
 62
 63 //共享内存区段的挂载,脱离和使用
 64 //理解共享内存区段就是一块大内存
 65 #include <stdio.h>
 66 #include <sys/shm.h>
 67 #include <sys/ipc.h>
 68 #include <errno.h>
 69 #define MY_SHM_ID 67483
 70 int main(  )
 71     {
 72         //共享内存区段的挂载和脱离
 73         int shmid,ret;
 74         void* mem;
 75         shmid=shmget( MY_SHM_ID,0,0 );
 76         if( shmid>=0 )
 77             {
 78                 mem=shmat( shmid,( const void* )0,0 );
 79                 //shmat()返回进程地址空间中指向区段的指针
 80                 if( ( int )mem!=-1 )
 81                     {
 82                         printf( "Shared memory was attached in our address space at %p/n",mem );
 83                         //向共享区段内存写入数据
 84                         strcpy( ( char* )mem,"This is a test string./n" );
 85                         printf( "%s/n",(char*)mem );
 86                         //脱离共享内存区段
 87                         ret=shmdt( mem );
 88                         if( ret==0 )
 89                             printf( "Successfully detached memory /n" );
 90                         else
 91                             printf( "Memory detached failed %d/n",errno );
 92                     }
 93                 else
 94                     printf( "shmat(  ) failed/n" );
 95
 96             }
 97         else
 98             printf( "shared memory segment not found/n" );
 99         return 0;
100     }
101 /*内存共享区段与旗语和消息队列不同,一个区段可以被锁定。
102   被锁定的区段不允许被交换出内存。这样做的优势在于,与其
103   把内存区段交换到文件系统,在某个应用程序调用时再交换回内存,
104   不如让它一直处于内存中,且对多个应用程序可见。从提升性能的角度
105   来看,很重要的。
106  */
107 int shmid;
108 //...
109 shmid=shmget( MY_SHM_ID,0,0 );
110 ret=shmctl( shmid,SHM_LOCK,0 );
111 if( ret==0 )
112     printf( "Locked!/n" );
113
114 /*使用旗语协调共享内存的例子
115   使用和编译命令
116   gcc -Wall test.c -o test
117   ./test create
118   ./test use a &
119   ./test use b &
120   ./test read &
121   ./test remove
122  */
123 #include <stdio.h>
124 #include <sys/shm.h>
125 #include <sys/ipc.h>
126 #include <sys/sem.h>
127 #include <string.h>
128 #include <stdlib.h>
129 #include <unistd.h>
130 #define MY_SHM_ID 34325
131 #define MY_SEM_ID 23234
132 #define MAX_STRING 200
133 typedef struct
134 {
135     int semID;
136     int counter;
137     char string[ MAX_STRING+1 ];
138 }MY_BLOCK_T;
139 int main(int argc,char** argv)
140     {
141         int shmid,ret,i;
142         MY_BLOCK_T* block;
143         struct sembuf sb;
144         char user;
145         //make sure there is a command
146         if( argc>=2 )
147             {
148                 //create the shared memory segment and init it
149                 //with the semaphore
150               if( !strncmp(argv[ 1 ],"create",6) )
151                     {
152                         //create the shared memory segment and semaphore
153                         printf( "Creating the shared memory/n" );
154                         shmid=shmget( MY_SHM_ID,sizeof( MY_BLOCK_T ),( IPC_CREAT|0666 ) );
155                         block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );
156                         block->counter=0;
157                         //create the semaphore and init
158                         block->semID=semget(MY_SEM_ID,1,( IPC_CREAT|0666 ));
159                         sb.sem_num=0;
160                         sb.sem_op=1;
161                         sb.sem_flg=0;
162                         semop( block->semID,&sb,1 );
163                         //now detach the segment
164                         shmdt( ( void* )block );
165                         printf( "Create the shared memory and semaphore successuflly/n" );
166
167                     }
168                 else if( !strncmp(argv[ 1 ],"use",3) )
169                     {
170                         /*use the segment*/
171                         //must specify  also a letter to write to the buffer
172                         if( argc<3 ) exit( -1 );
173                         user=( char )argv[ 2 ][ 0 ];
174                         //grab the segment
175                         shmid=shmget( MY_SHM_ID,0,0 );
176                         block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );
177
178                         /*##########重点就是使用旗语对共享区的访问###########*/
179                         for( i=0;i<100;++i )
180                         {
181                             sleep( 1 ); //设置成1s就会看到 a/b交替出现,为0则a和b连续出现
182                         //grab the semaphore
183                         sb.sem_num=0;
184                         sb.sem_op=-1;
185                         sb.sem_flg=0;
186                         if( semop( block->semID,&sb,1 )!=-1 )
187                             {
188                                 //write the letter to the segment buffer
189                                 //this is our CRITICAL SECTION
190                                 block->string[ block->counter++ ]=user;
191
192                                 sb.sem_num=0;
193                                 sb.sem_op=1;
194                                 sb.sem_flg=0;
195                                 if( semop( block->semID,&sb,1 )==-1 )
196                                     printf( "Failed to release the semaphore/n" );
197
198                             }
199                         else
200                             printf( "Failed to acquire the semaphore/n" );
201                         }
202
203                        //do some clear work
204                         ret=shmdt(( void*)block);
205
206                     }
207                 else if( !strncmp(argv[ 1 ],"read",4) )
208                     {
209                         //here we will read the buffer in the shared segment
210                         shmid=shmget( MY_SHM_ID,0,0 );
211                         if( shmid!=-1 )
212                             {
213                                 block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );
214                                 block->string[ block->counter+1 ]=0;
215                                 printf( "%s/n",block->string );
216                                 printf( "Length=%d/n",block->counter );
217                                 ret=shmdt( ( void*)block );
218                              }
219                         else
220                             printf( "Unable to read segment/n" );
221
222                     }
223                 else if( !strncmp(argv[ 1 ],"remove",6) )
224                     {
225                         shmid=shmget( MY_SHM_ID,0,0 );
226                         if( shmid>=0 )
227                             {
228                                 block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );
229                                 //remove the semaphore
230                                 ret=semctl( block->semID,0,IPC_RMID );
231                                 if( ret==0 )
232                                     printf( "Successfully remove the semaphore /n" );
233                                 //remove the shared segment
234                                 ret=shmctl( shmid,IPC_RMID,0 );
235                                 if( ret==0 )
236                                     printf( "Successfully remove the segment /n" );
237                             }
238                     }
239                 else
240                     printf( "Unkonw command/n" );
241             }
242         return 0;
243
244     }

转载于:https://www.cnblogs.com/zhangduan/archive/2012/05/30/2526499.html

Linux共享内存(二) (转载)相关推荐

  1. Linux共享内存(二)

    Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...

  2. Linux共享内存二维数组,linux系统编程--shmget shmat shmdt

    要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块 ...

  3. c++ 共享内存_关于Linux共享内存的实验 [二] - 原因

    关于Linux共享内存的实验 [一] 上文采用的"删文件"和"杀进程"的方法主要是为了快速演示实验现象,但这种做法不利于通过调试手段进一步探究其内在的逻辑.为此 ...

  4. 【Linux共享内存】

    Linux共享内存 一.基本概念 二.常用函数 1. shm_open 2. mmap 3. munmap 4. shm_unlink 5. ftruncate 三.使用示例 四.share内存不足解 ...

  5. linux 共享内存操作(shm_open、mmap、编译链接库:-lz -lrt -lm -lc都是什么库)

    文章目录 linux 共享内存操作(shm_open) 一.背景 二.函数使用说明 shm_open ftruncate(改变文件大小) mmap共享内存 三.示例代码 创建内存共享文件并写入数据 打 ...

  6. linux的共享内存,linux共享内存实际在哪里?

    我只想知道共享内存驻留在Linux系统中的位置?它在物理内存还是虚拟内存中?linux共享内存实际在哪里? 我知道有关进程的虚拟内存发送信箱,他们从不同的工艺处理和流程没有看到对方的记忆,但我们可以利 ...

  7. LINUX共享内存使用常见陷阱与分析(转)

    所谓共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式.是针对其他通信机制运行效率较低而设计的.往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥.其他进程能把同一段共 ...

  8. unix/linux共享内存应用与陷阱(转自三点水兽)

    共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区.在/proc/sys/kernel/目录下,记录着共享内存的一些限制,如一个共享内存区的最大字节数shmmax,系统范围内最大共享内存区 ...

  9. linux 共享内存_盘点那些linux 后台开发类常见问题及知识点

    一.linux和os: netstat :显示网络状态 tcpdump:主要是截获通过本机网络接口的数据,用以分析.能够截获当前所有通过本机网卡的数据包.它拥有灵活的过滤机制,可以确保得到想要的数据. ...

最新文章

  1. (转)Inno Setup入门(二十一)——Inno Setup类参考(7)
  2. python怎么安装pyecharts_基于Python安装pyecharts所遇的问题及解决方法
  3. 【知识星球】动态推理网络结构上新,不是所有的网络都是不变的
  4. python mysql异地备份_python脚本备份mysql数据库
  5. vi / vim 字符替换详解
  6. boost.asio系列——io_service
  7. python的scripts里没有pip_解决python scripts和pip缺失问题
  8. 利用ORB/AKAZE特征点进行图像配准
  9. 基于虚拟账号的邮件系统之×××
  10. 两步解决科来数据包生成器找不到网卡的问题
  11. 【超图+CESIUM】【基础API使用示例】48、超图|CESIUM - 漫游飞行效果
  12. 计算机大类专业学习c语言之重要性
  13. Halcon图像分割-多个threshold阈值处理算子讲解
  14. 开源的api文档管理系统
  15. arm板上简单运行main.cpp
  16. python换照片底色_Python学习给照片换底色(蓝底换红底)
  17. 新零售新模式:完整了解「快闪店」运作
  18. UI设计师是一群什么样的人?
  19. 简易的网上购物商城首页设计流程
  20. Dell PowerEdge T630安装GPU

热门文章

  1. java String类
  2. 不要为了“分库分表”而“分库分表”
  3. 混合云备份服务 > 产品简介 > 什么是混合云备份
  4. VCSA 6.7 U3部署(vCenter Server Appliance(VCSA)6.7 U3部署指南)
  5. 技术人员如何创业《一》- 产品及想法
  6. Maven学习总结(26)——maven update时,报:Preference node org.eclipse.wst.validation...
  7. Mysql学习总结(34)——Mysql 彻底解决中文乱码的问题
  8. 你属于开源性格测试六大分类中的哪一类呢
  9. 构造函数 返回值_JavaScript构造函数的简单介绍
  10. mysql备份到制定目录_写一个脚本定时自动备份mysql到指定目录