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 = -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 }
复制代码
编译运行:

1 [email protected]:/mnt/hgfs/C_libary# gcc -lrt -o shm_write shm_write.c
2 [email protected]:/mnt/hgfs/C_libary# ./shm_write test
3 hello linux
4 [email protected]:/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;
}
http://blog.csdn.net/maopig/article/details/16920907
时间: 2024-08-08 03:31:58

linux 共享内存shm_open实现进程间大数据交互的相关文章

Linux共享内存使用常见陷阱与分析

所谓共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式.是针对其他通信机制运行效率较低而设计的.往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥.其他进程能把同一段共享内存段“连接到”他们自己的地址空间里去.所有进程都能访问共享内存中的地址.如果一个进程向这段共享内存写了数据,所做的改动会即时被有访问同一段共享内存的其他进程看到.共享内存的使用大大降低了在大规模数据处理过程中内存的消耗,但是共享内存的使用中有很多的陷阱,一不注意就很容易导致程序崩溃. 超过共享内

linux 共享内存实现

说起共享内存,一般来说会让人想起下面一些方法:1.多线程.线程之间的内存都是共享的.更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享:2.父子进程间的内存共享.父进程以MAP_SHARED|MAP_ANONYMOUS选项mmap一块匿名内存,fork之后,其子孙进程之间就能共享这块内存.这种共享内存由于受到进程父子关系的限制,一般较少使用:3.mmap文件.多个进程mmap到同一个文件,实际上就是大家在共享文件page cache中的内存.不过文件牵涉到

一张图深度解析Linux共享内存的内核实现

一张图深度解析Linux共享内存的内核实现 Sailor_forever  sailing_9806#163.com http://blog.csdn.net/sailor_8318/article/details/39484747 (本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途.任何个人.媒体.其他网站不得私自抄袭:网络媒体转载请注明出处,增加原文链接,否则属于侵权行为.如有任何问题,请留言或者发邮件给sailing_9806#163.com)

【转】Linux共享内存编程实例

原文地址:http://blog.csdn.net/pcliuguangtao/article/details/6526119 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 6

Linux共享内存使用常见陷阱与分析 - 51CTO.COM http://os.51cto.com/art/201311/418977_all.htmIPC---共享内存

共享内存就是允许两个或多个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据时,不需要在客户进程和服务器进程之间幅值,因此是最快的一种IPC.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 注意:共享内存并未提供同步机制,也就是说,

Linux 共享内存使用

什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 特别提醒:共享内存并未提供同步机制,也就是说,在第一个进程结束对共

unix/linux共享内存应用与陷阱

unix/linux共享内存应用与陷阱 (2012-06-12 14:32) 标签:  linux  内存  分类: linux应用  共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区.在/proc/sys/kernel/目录下,记录着共享内存的一些限制,如一个共享内存区的最大字节数shmmax,系统范围内最大共享内存区标识符数shmmni等,可以手工对其调整,但不推荐这样做.一.应用共享内存的使用,主要有以下几个API:ftok().shmget().shmat().shmdt(

Linux共享内存实践(2)

shmdt函数 功能:将共享内存段与当前进程脱离 原型: int shmdt(const void *shmaddr); 参数: shmaddr: 由shmat所返回的指针 返回值: 成功返回0:失败返回-1 //实践:运行程序,观察ipcs输出 int main() { //获取或者打开共享内存 int shmid = shmget(0x15764221, 1024 * sizeof(int), 0666 | IPC_CREAT); if (shmid == -1) { err_exit("s

“非易失性内存”嫁接“内存计算”——高速安全的大数据时代来临

“非易失性内存”嫁接“内存计算” ——高速安全的大数据时代来临 题记 数据库奠基人Jim Gray:“磁带已经死了,磁盘已经落伍,闪存成为存储,内存才是王道”.“不管磁盘是否消融,闪存都是将来的一个趋势.” 石油一直直接影响着世累经济的发展速度和发展水平,现在,信息将发挥同样的作用.<经济学人>表示:“数据和信息日益成为商业的新能源,是一种与资本.劳动力并列的新经济元素”. 数据保护 大数据时代的机遇和挑战 大数据“风华正茂” 大数据时代,每两天的数据量就达到2ZB,相当于20世纪前人类文明所