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 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;
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值