linux 共享内存shm_open实现进程间大数据交互
linux 共享内存shm_open实现进程间大数据交互
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 = -;
int fd = -; char buf[] = {};
void* add_r = NULL; //创建或者打开一个共享内存
fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE);
if(- == (ret = fd))
{
perror("shm failed: ");
goto _OUT;
} //调整确定文件共享内存的空间
ret = ftruncate(fd, FILE_SIZE);
if(- == 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(- == ret)
{
perror("munmap add_r faile: ");
goto _OUT;
}
//删除内存共享
shm_unlink(SHMNAME);
if(- == 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 = -;
int fd = -; void* add_w = NULL; //创建或者打开一个共享内存
fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE);
if(- == (ret = fd))
{
perror("shm failed: ");
goto _OUT;
} //调整确定文件共享内存的空间
ret = ftruncate(fd, FILE_SIZE);
if(- == 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(- == ret)
{
perror("munmap add_w faile: ");
goto _OUT;
}
//删除内存共享
/*shm_unlink(SHMNAME);
if(-1 == ret)
{
perror("shm_unlink faile: ");
goto _OUT;
}*/ _OUT:
return ret;
} /*shm_write.c写入/读出共享内存区*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h> int main(int argc,char **argv)
{
int shm_id;
struct stat buf;
char *ptr; if(argc!=)
{
printf("usage:shm_open <pathname>\n");
exit();
}
shm_id=shm_open(argv[],O_RDWR|O_CREAT,);/*创建共享内存区*/
ftruncate(shm_id,);/*修改共享区大小*/
fstat(shm_id,&buf);
ptr=mmap(NULL,buf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,);/*连接共享内存区*/
strcpy(ptr,"hello linux");/*写入共享内存区*/
printf("%s\n",ptr);/*读出共享内存区*/
shm_unlink(argv[]);/*删除共享内存区*/
}
复制代码
编译运行: root@linux:/mnt/hgfs/C_libary# gcc -lrt -o shm_write shm_write.c
root@linux:/mnt/hgfs/C_libary# ./shm_write test
hello linux
root@linux:/mnt/hgfs/C_libary# ftruncate()函数 功能: 调整文件或共享内存区大小
头文件: #include <unistd.h>
函数原形: int ftruncate(int fd,off_t length);
参数:
fd 描述符
length 大小
返回值: 成功返回0,出错返回- 当打开一个已存在的共享内存区对象时,我们可调用fstat来获取有关该对象的信息 fstat()函数
功能: 获得文件或共享内存区的信息
头文件: #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
函数原形: int stat(const char *file_name,struct stat *buf);
参数:
file_name 文件名
buf stat结构
返回值: 成功返回0,出错返回- 对于普通文件stat结构可以获得12个以上的成员信息,然而当fd指代一个共享内存区对象时,只有四个成员含有信息。
struct stat{
mode_t st_mode;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
};
复制代码
示例代码: 复制代码
/*shm_show.c显示共享区信息*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h> int main(int argc,char **argv)
{
int shm_id;
struct stat buf; if(argc!=)
{
printf("usage:shm_open <pathname>\n");
exit();
}
shm_id=shm_open(argv[],O_RDWR|O_CREAT,);/*创建共享内存*/
printf("size :%d\n",buf.st_size); /*修改前共享内存区大小*/
ftruncate(shm_id,);/*修改共享内存的大小*/
fstat(shm_id,&buf); /*把共享内存的信息记录到buf中*/
printf("uid_t:%d\n",buf.st_uid); /*共享内存区所有者ID*/
printf("git_t:%d\n",buf.st_gid); /*共享内存区所有者组ID*/
printf("size :%d\n",buf.st_size); /*修改后共享内存区大小*/
} 客户服务段两进程通信实例: 服务端 #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!=)
{
printf("usage:shm_open<pathname>\n");
return -;
} shm_id=shm_open(argv[],O_RDWR|O_CREAT,);/*第一步:创建共享内存区*/
if (shm_id==-)
{
printf( "open shared memory error.errno=%d,desc=%s.\n", errno, strerror(errno));
return -;
} ftruncate(shm_id,);/*第二步:调整共享内存区大小,shmid问shm_open的返回值*/
sem=sem_open(argv[],O_CREAT,,);/*创建信号量*/
if (sem==SEM_FAILED)
{
printf( "open semaphore error.errno=%d,desc=%s.\n", errno, strerror(errno));
return -;
} ptr=mmap(NULL,,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,);/*第三步:连接共享内存区*/
strcpy(ptr,"\0"); sem_wait(sem);/*第四步:申请信号量*/
printf("server : %s\n",ptr);/*输入共享内存区内容*/
strcpy(ptr,"\0");/*清空共享内存区*/ sem_unlink(argv[]);/*第五步:删除信号量*/
shm_unlink(argv[]);/*第六步:删除共享内存区*/ return ;
}
客户端: #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!=)
{
printf("usage:shm_open <pathname>\n");
return -;
} shm_id=shm_open(argv[],O_RDWR,);/*第一步:打开共享内存区*/
if (shm_id==-)
{
printf( "open shared memory error.errno=%d,desc=%s.\n", errno, strerror(errno));
return -;
}
else
{
printf( "open shared memory ok.\n");
} sem=sem_open(argv[],);/*打开信号量*/
if (sem==SEM_FAILED)
{
printf( "open semaphore error.errno=%d,desc=%s.\n", errno, strerror(errno));
return -;
}
else
{
printf( "open semaphore ok.\n");
} ptr=mmap(NULL,,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,);/*连接共享内存区*/ fgets(ptr,,stdin);/*从键盘读入数据到共享内存区*/
printf("user : %s",ptr); sem_post(sem);/*释放信号量*/ return ;
}
http://blog.csdn.net/maopig/article/details/16920907
linux 共享内存shm_open实现进程间大数据交互的更多相关文章
- python的进程间的数据交互
#先来看下如何实现多进程 # multiprocessing 这个是python的多进程的模块,我们会用到这个模块的很多方法 from multiprocessing import Process i ...
- 【VS开发】内存映射文件进程间共享内存
内存映射文件进程间共享内存 内存映射文件的另一个功能是在进程间共享数据,它提供了不同进程共享内存的一个有效且简单的方法.后面的许多例子都要用到共享内存.共享内存主要是通过映射机制实现的.Windows ...
- Linux 共享内存 详解
一.什么是共享内存区 共享内存区是最快的可用IPC形式.它允许多个不相关的进程去访问同一部分逻辑内存.如果需要在两个运行中的进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存区映射到 ...
- Linux共享内存使用常见陷阱与分析
所谓共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式.是针对其他通信机制运行效率较低而设计的.往往与其它通信机制,如 信号量结合使用,来达到进程间的同步及互斥.其他进程能把同一段 ...
- linux 共享内存实现
说起共享内存,一般来说会让人想起下面一些方法:1.多线程.线程之间的内存都是共享的.更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享:2.父子进程间的内存共享 ...
- Linux 共享内存编程
共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- Linux共享内存
1.什么是共享内存在前面讲虚拟内存机制时,有讲到Linux的内存映射机制:初始化虚拟内存区域时,会把虚拟内存和磁盘文件对象对应起来.由于内存映射机制,一个磁盘文件对象可被多个进程共享访问,也可被多个进 ...
- 关于linux 共享内存查看已经完整释放
完整删除共享内存脚本 #!/bin/sh function rmshm() { zero_status=`ipcs -m|awk '{print $6}'|grep -w 0|wc -l` if [ ...
随机推荐
- 使用Apache FtpServer
Java大法一统天下.遇到任何问题,先查一下Java中的解决方案. 地球上的许多事情,在Java中都能找到完美的解决方案. FtpServer是apache MINA项目的一个子项目,它实现了一个ft ...
- 何时使用copy,strong,weak,assign关键字 定义属性
现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained ...
- eclipse 快捷键设置
“window→Preferences→General→Keys→你想设置的快捷键" PS(Postscript)我常用的快捷键: 撤销 Undo Ctrl+Z 还原 Redo ...
- 关于域名如何指向WordPress homepage问题的解决
http://genuinelx.org/oldversion.php/archives/19为解决这个问题真的费了我半天的时间= = ,不写出来真的难以抒发苦闷. 下午VPS开通了,虽然有个ip被墙 ...
- Python学习笔记014——迭代器 Iterator
1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...
- VS2010中遇到_WIN32_WINNT not defined
VS2010中编程时遇到这个问题 _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h) 解决办法: ...
- VC6.0编译DLL,使用VS2010调用问题及解决方法
1.做驱动的时候.做应用程序须要和驱动通信,必须建立一个DLL. 2.由于客户使用版本号太低,须要使用到VC6.0编写DLL 3.在VC6.0上编写DLL的时候,导出的函数名会出现和原函数名不正确,导 ...
- USB的中断说明
STM32的USB模块可以产生三种中断:USB唤醒中断.USB高优先级中断和USB低优先级中断,在STM32的参考手册中没有详细说明这三种中断对应哪些事件,现说明如下: 1)USB唤醒中断:在中断向量 ...
- django post和get 比较
当我们提交表单仅仅需要获取数据时就可以用GET: 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST. 在这个搜索书籍的例子里,我们 ...
- 常用IP核
前言 记录自己用到的模块,随时补充. 主要分类: 一.常用模块 1-FIFO FIFO分为两种,一是输入输出时钟相同(Common clock)的 fifo ;二是输入输出时钟不相同(Independ ...