Linux共享内存编程实例

原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119

/*共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间)从而使得这些进程可以相互通信。在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共享内存应用编程接口API允许一个进程使用公共内存区段。但是对内存的共享访问其复杂度也相应增加。共享内存的优点是简易性。使用消息队列时,一个进程要向队列中写入消息,这要引起从用户地址空间向内核地址空间的一次复制,同样一个进程进行消息读取时也要进行一次复制。共享内存的优点是完全省去了这些操作。共享内存会映射到进程的虚拟地址空间,进程对其可以直接访问,避免了数据的复制过程。因此,共享内存是GNU/Linux现在可用的最快速的IPC机制。进程退出时会自动和已经挂接的共享内存区段分离,但是仍建议当进程不再使用共享区段时调用shmdt来卸载区段。注意,当一个进程分支出父进程和子进程时,父进程先前创建的所有共享内存区段都会被子进程继承。如果区段已经做了删除标记(在前面以IPC——RMID指令调用shmctl),而当前挂接数已经变为0,这个区段就会被移除。*/
/*shmget(  )  创建一个新的共享内存区段取得一个共享内存区段的描述符shmctl(  )  取得一个共享内存区段的信息为一个共享内存区段设置特定的信息移除一个共享内存区段shmat(  )   挂接一个共享内存区段shmdt(  )   于一个共享内存区段的分离*/
//创建一个共享内存区段,并显示其相关信息,然后删除该内存共享区
#include <stdio.h>
#include <unistd.h>  //getpagesize(  )
#include <sys/ipc.h>
#include <sys/shm.h>
#define MY_SHM_ID 67483
int main(  ){//获得系统中页面的大小printf( "page size=%d/n",getpagesize(  ) );//创建一个共享内存区段int shmid,ret;shmid=shmget( MY_SHM_ID,4096,0666|IPC_CREAT );//创建了一个4KB大小共享内存区段。指定的大小必须是当前系统架构//中页面大小的整数倍if( shmid>0 )printf( "Create a shared memory segment %d/n",shmid );//获得一个内存区段的信息struct shmid_ds shmds;//shmid=shmget( MY_SHM_ID,0,0 );//示例怎样获得一个共享内存的标识符ret=shmctl( shmid,IPC_STAT,&shmds );if( ret==0 ){printf( "Size of memory segment is %d/n",shmds.shm_segsz );printf( "Numbre of attaches %d/n",( int )shmds.shm_nattch );}else{printf( "shmctl(  ) call failed/n" );}//删除该共享内存区ret=shmctl( shmid,IPC_RMID,0 );if( ret==0 )printf( "Shared memory removed /n" );elseprintf( "Shared memory remove failed /n" );return 0;}//共享内存区段的挂载,脱离和使用
//理解共享内存区段就是一块大内存
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>
#define MY_SHM_ID 67483
int main(  ){//共享内存区段的挂载和脱离int shmid,ret;void* mem;shmid=shmget( MY_SHM_ID,0,0 );if( shmid>=0 ){mem=shmat( shmid,( const void* )0,0 );//shmat()返回进程地址空间中指向区段的指针if( ( int )mem!=-1 ){printf( "Shared memory was attached in our address space at %p/n",mem );//向共享区段内存写入数据strcpy( ( char* )mem,"This is a test string./n" );printf( "%s/n",(char*)mem );//脱离共享内存区段ret=shmdt( mem );if( ret==0 )printf( "Successfully detached memory /n" );elseprintf( "Memory detached failed %d/n",errno );}elseprintf( "shmat(  ) failed/n" );}elseprintf( "shared memory segment not found/n" );return 0;}
/*内存共享区段与旗语和消息队列不同,一个区段可以被锁定。被锁定的区段不允许被交换出内存。这样做的优势在于,与其把内存区段交换到文件系统,在某个应用程序调用时再交换回内存,不如让它一直处于内存中,且对多个应用程序可见。从提升性能的角度来看,很重要的。*/
int shmid;
//...
shmid=shmget( MY_SHM_ID,0,0 );
ret=shmctl( shmid,SHM_LOCK,0 );
if( ret==0 )printf( "Locked!/n" );/*使用旗语协调共享内存的例子使用和编译命令gcc -Wall test.c -o test./test create./test use a &./test use b &./test read &./test remove */
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MY_SHM_ID 34325
#define MY_SEM_ID 23234
#define MAX_STRING 200
typedef struct
{int semID;int counter;char string[ MAX_STRING+1 ];
}MY_BLOCK_T;
int main(int argc,char** argv){int shmid,ret,i;MY_BLOCK_T* block;struct sembuf sb;char user;//make sure there is a commandif( argc>=2 ){//create the shared memory segment and init it//with the semaphoreif( !strncmp(argv[ 1 ],"create",6) ){//create the shared memory segment and semaphoreprintf( "Creating the shared memory/n" );shmid=shmget( MY_SHM_ID,sizeof( MY_BLOCK_T ),( IPC_CREAT|0666 ) );block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );block->counter=0;//create the semaphore and initblock->semID=semget(MY_SEM_ID,1,( IPC_CREAT|0666 ));sb.sem_num=0;sb.sem_op=1;sb.sem_flg=0;semop( block->semID,&sb,1 );//now detach the segmentshmdt( ( void* )block );printf( "Create the shared memory and semaphore successuflly/n" );}else if( !strncmp(argv[ 1 ],"use",3) ){/*use the segment*///must specify  also a letter to write to the bufferif( argc<3 ) exit( -1 );user=( char )argv[ 2 ][ 0 ];//grab the segmentshmid=shmget( MY_SHM_ID,0,0 );block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );/*##########重点就是使用旗语对共享区的访问###########*/for( i=0;i<100;++i ){sleep( 1 ); //设置成1s就会看到 a/b交替出现,为0则a和b连续出现//grab the semaphoresb.sem_num=0;sb.sem_op=-1;sb.sem_flg=0;if( semop( block->semID,&sb,1 )!=-1 ){//write the letter to the segment buffer//this is our CRITICAL SECTIONblock->string[ block->counter++ ]=user;sb.sem_num=0;sb.sem_op=1;sb.sem_flg=0;if( semop( block->semID,&sb,1 )==-1 )printf( "Failed to release the semaphore/n" );}elseprintf( "Failed to acquire the semaphore/n" );}//do some clear workret=shmdt(( void*)block);}else if( !strncmp(argv[ 1 ],"read",4) ){//here we will read the buffer in the shared segmentshmid=shmget( MY_SHM_ID,0,0 );if( shmid!=-1 ){block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );block->string[ block->counter+1 ]=0;printf( "%s/n",block->string );printf( "Length=%d/n",block->counter );ret=shmdt( ( void*)block );}elseprintf( "Unable to read segment/n" );}else if( !strncmp(argv[ 1 ],"remove",6) ){shmid=shmget( MY_SHM_ID,0,0 );if( shmid>=0 ){block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );//remove the semaphoreret=semctl( block->semID,0,IPC_RMID );if( ret==0 )printf( "Successfully remove the semaphore /n" );//remove the shared segmentret=shmctl( shmid,IPC_RMID,0 );if( ret==0 )printf( "Successfully remove the segment /n" );}}elseprintf( "Unkonw command/n" );}return 0;}

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

  1. Linux共享内存(二) (转载)

    1 /*共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间) 2 从而使得这些进程可以相互通信. 3 在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共 ...

  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. linux 共享内存_盘点那些linux 后台开发类常见问题及知识点

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

  9. 宋宝华:世上最好的共享内存(Linux共享内存最透彻的一篇)上集

    共享单车.共享充电宝.共享雨伞,世间的共享有千万种,而我独爱共享内存. 早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进 ...

最新文章

  1. 美国多个州对谷歌提起新的反垄断诉讼
  2. 解放双手!接私活必备的Java开源项目
  3. 为什么现在腿会抽筋了?
  4. python 语音播放_基于Python编写的语音播放软件
  5. linux java 部署 生产环境
  6. 结组项目-四则运算3
  7. docker内存阀值_kubernetes调度之资源耗尽处理配置
  8. Python学习汇总,做数据采集的一些小技巧,收获满满
  9. sql 获取第10到20个记录
  10. jdk1.8 HashMap ConcurrentHashMap
  11. Wannafly挑战赛18B 随机数
  12. 测试理论----软件测试六大测试类型
  13. 南开大学校园邮箱pop3地址
  14. Shell中if的使用详解_与||的使用详解
  15. 02笔记 离散数学——命题逻辑——基于离散数学(第3版)_章炯民,陶增乐
  16. 诗歌(11)—东栏梨花
  17. hdu 2097 Java Sky数
  18. bat 命令返回结果_初探PowerShell命令入门级
  19. Aspose.PDF for Java系列5-转化PDF文档为Word
  20. 实现财务自由 之 打新股(申购新股),A 股怎么打新,打新的注意事项

热门文章

  1. Java中int转Double再转换成百分数并应用在求同比昨日增长率
  2. spring系列-注解驱动原理及源码-spring容器创建流程
  3. java类加载器、双亲委派、沙箱安全机制全都让你整明白(三万字,收藏慢慢啃)
  4. Review meeting还开不开?
  5. java基础知识讲解(一)数据类型和运算符
  6. cad无法加载arx文件_多年经验总结CAD技巧8
  7. 如何设计让用户喜欢且令人尖叫的产品?
  8. 阿里技术协会(ATA)11月系列精选文集
  9. 实例解说Linux命令行uniq (转)
  10. WebSocket 1.0的学习和简单使用