设为首页 收藏本站
查看: 793|回复: 0

[经验分享] linux 共享内存shm_open实现进程间大数据交互

[复制链接]

尚未签到

发表于 2016-4-1 10:17:55 | 显示全部楼层 |阅读模式
read.c


#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <sys/mman.h>

#include <string.h>

#include <errno.h>

#include <unistd.h>



/*

int shm_open(const char *name, int oflag, mode_t mode);

//创建或打开一个共享内存,成功返回一个整数的文件描述符,错误返回-1。

1.name:共享内存区的名字;

2.标志位;open的标志一样

3.权限位

int shm_unlink(const char *name);



编译时要加库文件-lrt

*/



#define SHMNAME "shm_ram"

#define OPEN_FLAG O_RDWR|O_CREAT

#define OPEN_MODE 00777

#define FILE_SIZE 4096*4





int main(void)

{

int ret = -1;

int fd = -1;



char buf[4096] = {0};

void* add_r = NULL;



//创建或者打开一个共享内存
  fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE);

if(-1 == (ret = fd))

{

perror("shm failed: ");

goto _OUT;

}


//调整确定文件共享内存的空间

ret = ftruncate(fd, FILE_SIZE);

if(-1 == ret)

{

perror("ftruncate faile: ");

goto _OUT;

}


//映射目标文件的存储区
  add_r = mmap(NULL, FILE_SIZE, PROT_READ, MAP_SHARED, fd, SEEK_SET);

if(NULL == add_r)

{

perror("mmap add_r failed: ");

goto _OUT;

}







//memcpy 内存共享 写入内容
memcpy(buf, add_r, sizeof(buf));


printf("buf = %s\n", buf);



//取消映射
  ret = munmap(add_r, FILE_SIZE);

if(-1 == ret)

{

perror("munmap add_r faile: ");

goto _OUT;

}

//删除内存共享
shm_unlink(SHMNAME);

if(-1 == ret)

{

perror("shm_unlink faile: ");

goto _OUT;

}



_OUT:  

return ret;

}







write.c





#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <sys/mman.h>

#include <string.h>

#include <errno.h>

#include <unistd.h>



/*

int shm_open(const char *name, int oflag, mode_t mode);

//创建或打开一个共享内存,成功返回一个整数的文件描述符,错误返回-1。

1.name:共享内存区的名字;

2.标志位;open的标志一样

3.权限位

int shm_unlink(const char *name);



编译时要加库文件-lrt

*/



#define SHMNAME "shm_ram"

#define OPEN_FLAG O_RDWR|O_CREAT

#define OPEN_MODE 00777

#define FILE_SIZE 4096*4





int main(void)

{

int ret = -1;

int fd = -1;



void* add_w = NULL;



//创建或者打开一个共享内存

fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE);

if(-1 == (ret = fd))

{

perror("shm failed: ");

goto _OUT;

}



//调整确定文件共享内存的空间

ret = ftruncate(fd, FILE_SIZE);

if(-1 == ret)

{

perror("ftruncate faile: ");

goto _OUT;

}


//映射目标文件的存储区
add_w = mmap(NULL, FILE_SIZE, PROT_WRITE, MAP_SHARED, fd, SEEK_SET);

if(NULL == add_w)

{

perror("mmap src failed: ");

goto _OUT;

}





//memcpy 内存共享 写入内容
  memcpy(add_w, "howaylee", sizeof("howaylee"));



//取消映射

ret = munmap(add_w, FILE_SIZE);

if(-1 == ret)

{

perror("munmap add_w faile: ");

goto _OUT;

}

//删除内存共享

/*shm_unlink(SHMNAME);

if(-1 == ret)

{

perror("shm_unlink faile: ");

goto _OUT;

}*/



_OUT:  

return ret;
  }
  

  

  


1
/*shm_write.c写入/读出共享内存区*/
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <sys/mman.h>
8 #include <unistd.h>
9
10 int main(int argc,char **argv)
11 {
12     int shm_id;
13     struct stat buf;
14     char *ptr;
15
16     if(argc!=2)
17     {
18         printf("usage:shm_open <pathname>\n");
19         exit(1);
20     }
21     shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);/*创建共享内存区*/
22     ftruncate(shm_id,100);/*修改共享区大小*/
23     fstat(shm_id,&buf);
24     ptr=mmap(NULL,buf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);/*连接共享内存区*/
25     strcpy(ptr,"hello linux");/*写入共享内存区*/
26     printf("%s\n",ptr);/*读出共享内存区*/
27     shm_unlink(argv[1]);/*删除共享内存区*/
28 }
DSC0000.gif


  

编译运行:


1 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o shm_write shm_write.c
2 root@linux:/mnt/hgfs/C_libary# ./shm_write test
3 hello linux
4 root@linux:/mnt/hgfs/C_libary#



  


1
ftruncate()函数 3 功能:    调整文件或共享内存区大小
4 头文件:    #include <unistd.h>
5 函数原形:    int ftruncate(int fd,off_t length);
6 参数:   
7     fd          描述符
8     length       大小
9 返回值:    成功返回0,出错返回-1
10
11 当打开一个已存在的共享内存区对象时,我们可调用fstat来获取有关该对象的信息
12
13 fstat()函数
14 功能:    获得文件或共享内存区的信息
15 头文件:    #include <unistd.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 函数原形:    int stat(const char *file_name,struct stat *buf);
19 参数:   
20 file_name          文件名
21 buf               stat结构
22 返回值:    成功返回0,出错返回-1
23
24 对于普通文件stat结构可以获得12个以上的成员信息,然而当fd指代一个共享内存区对象时,只有四个成员含有信息。
25 struct stat{
26     mode_t st_mode;
27     uid_t st_uid;
28     gid_t st_gid;
29     off_t st_size;
30 };



  

示例代码:




1 /*shm_show.c显示共享区信息*/
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <fcntl.h>
8 #include <sys/mman.h>
9
10 int main(int argc,char **argv)
11 {
12     int shm_id;
13         struct stat buf;
14
15         if(argc!=2)
16         {
17             printf("usage:shm_open <pathname>\n");
18             exit(1);
19         }
20         shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);/*创建共享内存*/
21         printf("size :%d\n",buf.st_size); /*修改前共享内存区大小*/
22         ftruncate(shm_id,100);/*修改共享内存的大小*/
23         fstat(shm_id,&buf); /*把共享内存的信息记录到buf中*/
24         printf("uid_t:%d\n",buf.st_uid); /*共享内存区所有者ID*/
25         printf("git_t:%d\n",buf.st_gid); /*共享内存区所有者组ID*/
26         printf("size :%d\n",buf.st_size); /*修改后共享内存区大小*/
27 }

  

  客户服务段两进程通信实例:
  服务端
  #include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>

int main(int argc,char **argv)
{
  int shm_id;
  char *ptr;
  sem_t *sem;

  if (argc!=2)
  {
  printf("usage:shm_open<pathname>\n");
  return -1;
  }

  shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);/*第一步:创建共享内存区*/
  if (shm_id==-1)
  {
  printf( "open shared memory error.errno=%d,desc=%s.\n", errno, strerror(errno));
  return -1;
  }

  ftruncate(shm_id,100);/*第二步:调整共享内存区大小,shmid问shm_open的返回值*/
  sem=sem_open(argv[1],O_CREAT,0644,0);/*创建信号量*/
  if (sem==SEM_FAILED)
  {
  printf( "open semaphore error.errno=%d,desc=%s.\n", errno, strerror(errno));
  return -1;
  }

  ptr=mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);/*第三步:连接共享内存区*/
  strcpy(ptr,"\0");

  sem_wait(sem);/*第四步:申请信号量*/
  printf("server : %s\n",ptr);/*输入共享内存区内容*/
  strcpy(ptr,"\0");/*清空共享内存区*/

  sem_unlink(argv[1]);/*第五步:删除信号量*/
  shm_unlink(argv[1]);/*第六步:删除共享内存区*/

  return 0;
}

  客户端:
  #include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>

int main(int argc,char **argv)
{
  int shm_id;
  char *ptr;
  sem_t *sem;

  if (argc!=2)
  {
  printf("usage:shm_open <pathname>\n");
  return -1;
  }

  shm_id=shm_open(argv[1],O_RDWR,0);/*第一步:打开共享内存区*/
  if (shm_id==-1)
  {
  printf( "open shared memory error.errno=%d,desc=%s.\n", errno, strerror(errno));
  return -1;
  }
  else
  {
  printf( "open shared memory ok.\n");
  }

  sem=sem_open(argv[1],0);/*打开信号量*/
  if (sem==SEM_FAILED)
  {
  printf( "open semaphore error.errno=%d,desc=%s.\n", errno, strerror(errno));
  return -1;
  }
  else
  {
  printf( "open semaphore ok.\n");
  }

  ptr=mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);/*连接共享内存区*/

  fgets(ptr,10,stdin);/*从键盘读入数据到共享内存区*/
  printf("user : %s",ptr);


sem_post(sem);/*释放信号量*/


  return 0;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-198307-1-1.html 上篇帖子: Linux Centos6挂载本地ISO光驱镜像 下篇帖子: -bash: crontab: command not found
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表