扩展阅读
  • linux c/c++ IP字符串转换成可比较大小的数字
  • 在win分区上安装linux和独立分区安装linux有什么区别?可以同时安装吗?(两个linux系统)
  • linux哪个版本好?linux操作系统版本详细介绍及选择方案推荐
  • 在虚拟机上安装的linux上,能像真的linux系统一样开发linux程序么?
  • secureCRT下Linux终端汉字乱码解决方法
  • 我重装window后,把linux的引导区覆盖了,进不了linux怎么办?急啊,望热心的人帮助 (现在有linux的盘)
  • Linux c字符串中不可打印字符转换成16进制
  • 红旗Linux主机可以通过127.0.0.1访问,但如何是连网的Win2000机器通过Linux的IP去访问Linux
  • Linux常用命令介绍:更改所属用户群组或档案属性
  • 安装vmware软件,不用再安装linux系统,就可以模拟linux系统了,然后可以在其上学习一下LINUX下的基本操作 了?
  • linux命令大全详细分类介绍及常用linux命令文档手册下载
  • 我重装window后,把linux的引导区覆盖了,进不了linux怎么办?急啊,望热心的人帮助 (现在没有linux的盘,只有DOS启动盘)
  • Linux Kernel 'sctp_v6_xmit()'函数信息泄露漏洞
  • 如何让win2000和linux共存。我装好WIN2000,再装LINUX7.0,但LILO只能找到LINUX,不能引导WIN2000
  • linux c下利用srand和rand函数生成随机字符串
  • 在windows中的VMware装了个linux,主板有两个串口,能做windows和linux的串口通信测试么,怎么测试这两个串口在linux是有效
  • Docker官方镜像将会使用Alpine Linux替换Ubuntu
  • 我们网站的服务器从windows2000迁往linux,ASP程序继续使用,可是我连LINUX的皮毛都不了解,大家告诉我LINUX下怎么建网站??
  • Linux下chmod命令详细介绍及用法举例
  • 中文Linux与西文Linus分别哪一个版是权威?I认为是:中科软的白旗Linux与西文的绿帽子Linux!大家的看法呢?
  • Linux下c基于openssl生成MD5的函数
  • Windows2000和Linux双操作系统,Linux系统有问题,我直接把Linux分区删除后,Windows2000进不去了,怎么办???
  •  
    当前位置:  编程语言>c/c++

    Linux 共享内存介绍及实现代码

     
        发布时间:2013-9-7  


        本文导语:  共享内存是进程间通信中最简单的方式之一。共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间)从而使得这些进程可以相互通信。在GNU/Linux中所有的进程都有唯一的虚...

        共享内存进程间通信中最简单的方式之一。共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间)从而使得这些进程可以相互通信。在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共享内存应用编程接口API允许一个进程使用公共内存区段。但是对内存的共享访问复杂度也相应增加。共享内存的优点是简易性。

        使用消息队列时,一个进程要向队列中写入消息,这要引起从用户地址空间向内核地址空间的一次复制,同样一个进程进行消息读取时也要进行一次复制。共享内存的优点是完全省去了这些操作。共享内存会映射到进程的虚拟地址空间,进程对其可以直接访问,避免了数据的复制过程。

        因此,共享内存是GNU/Linux现在可用的最快速的IPC机制。进程退出时会自动和已经挂接的共享内存区段分离,但是仍建议当进程不再使用共享区段时调用shmdt来卸载区段。注意,当一个进程分支出父进程和子进程时,父进程先前创建的所有共享内存区段都会被子进程继承

       如果区段已经做了删除标记(在前面以IPC——RMID指令调用shmctl),而当前挂接数已经变为0,这个区段就会被移除。

       Linux下共享内存常用操作函数:

     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" );
            else
                printf( "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" );
                            else
                                printf( "Memory detached failed %d/n",errno );
                        }
                    else
                        printf( "shmat(  ) failed/n" );
                }
            else
                printf( "shared memory segment not found/n" );
            return 0;
        }


       内存共享区段与旗语和消息队列不同,一个区段可以被锁定。被锁定的区段不允许被交换出内存。这样做的优势在于,与其把内存区段交换到文件系统,在某个应用程序调用时再交换回内存,不如让它一直处于内存中,且对多个应用程序可见。从提升性能的角度来看,很重要的。


    #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 command
            if( argc>=2 )
                {
                    //create the shared memory segment and init it
                    //with the semaphore
                  if( !strncmp(argv[ 1 ],"create",6) )
                        {
                            //create the shared memory segment and semaphore
                            printf( "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 init
                            block->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 segment
                            shmdt( ( 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 buffer
                            if( argc<3 ) exit( -1 );
                            user=( char )argv[ 2 ][ 0 ];
                            //grab the segment
                            shmid=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 semaphore
                            sb.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 SECTION
                                    block->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" );
                                }
                            else
                                printf( "Failed to acquire the semaphore/n" );
                            }
                           //do some clear work
                            ret=shmdt(( void*)block);
                        }
                    else if( !strncmp(argv[ 1 ],"read",4) )
                        {
                            //here we will read the buffer in the shared segment
                            shmid=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 );
                                 }
                            else
                                printf( "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 semaphore
                                    ret=semctl( block->semID,0,IPC_RMID );
                                    if( ret==0 )
                                        printf( "Successfully remove the semaphore /n" );
                                    //remove the shared segment
                                    ret=shmctl( shmid,IPC_RMID,0 );
                                    if( ret==0 )
                                        printf( "Successfully remove the segment /n" );
                                }
                        }
                    else
                        printf( "Unkonw command/n" );
                }
            return 0;
        }


    • 本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
      本站(WWW.)站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.
      转载请注明:文章转载自:[169IT-IT技术资讯]
      本文标题:Linux 共享内存介绍及实现代码
    相关文章推荐:
  • linux下通过crond实现自动执行程序
  • Linux和Unix相对WIN、NETWARE有什么好处?他们之间有什么区别?WIN、NETWARE能实现的功能LINUX和UNIX能实现吗?
  • linux下grep命令实现查找多个关键字(与关系和或关系)
  • linux下如实现与window下的驱动器实现文件共享??
  • Linux下C语言strstr()查找子字符串位置函数详细介绍(strstr原型、实现及用法)
  • windows 下的PortTunnel 在linux下怎么实现?或者相应的已经实现的软件?端口映射
  • Linux c socket编程:简单的客户端(client)和服务端(server)实现
  • 在linux下如何编程实现nslookup命令实现的IP地址和域名互相转换的功能?
  • 我需要一个模型,在 LINUX C 下。实现线程间的控制,执行,阻塞,再执行。。。。。不知道如何实现。
  • 我想做linux下的还原备份,实现与还原精灵虚拟还原等一样的功能,应该怎么做?另外现在有实现这种功能的成熟产品是哪一种?
  • 关于linux c程序实现自动实现telnet的问题
  • 请问高手linux中用md5来实现一串字符串的加密,用c++/c实现
  • 在linux实现在任意给定的目录查找文需要的件的程序? 下面的实现思路可不可以呢????
  • 请问:有没有人在Linux下实现过计费网关?
  • 关于XP系统下批处理文件如何实现执行linux下脚本,从而实现版本的自动化编译
  • 如何在linux下实现event事件机制
  • linux 下如何使用消息队列实现群聊天室
  • 我有两台linux 服务器,如果让他们实现负载均衡?
  • 求助!如何实现一个类似于linux中的命令回调功能?
  • 想设计几个简单的通信程序,在linux环境下编译通信,怎么实现?
  • 送分:LINUX 下如何实现双机的备份和同步?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3