Linux 共享内存例子

Linux环境下进程之间通过内存共享实现通信的方式有很多种。


1.  shm_XXX 这种函数,可以实现在不同进程之间(尤其是非父母进程之间)进行内存共享


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

read.c文件

#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.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;
}

编译的时候gcc加上-lrt,分别编译出write,read。

./write之后./read会输出 "buf = howaylee"


2. shmget等函数也可以


client.c文件

/* 编译命令:gcc -o client client.c -g*/
#include<sys/sem.h>
#include<time.h>
#include<sys/ipc.h>

#define SEGSIZE  1024
#define READTIME 1

union semun
{
    int              val;
    struct semid_ds  *buf;
    unsigned short   *array;
}arg;

/* 打印程序的执行时间函数 */
void out_time(void)
{
    static long start = 0;
    time_t      tm;

    if (start == 0)
    {
        tm = time(NULL);
        start = (long)tm;
        printf("now start \n");
    }

    printf("second: %d\n", (long)(time(NULL)) - start);
}

/* 创建信号量 */
int new_sem(key_t key)
{
    union semun sem;
    int semid;
    sem.val = 0;
    semid = semget(key, 0, 0);

    if (-1 ==  semid)
    {
        printf("create semaphore error\n");
        exit(-1);
    }

    return semid;
}

/* 信号量等待函数,等待信号量的值变为0 */
void wait_v(int semid)
{
    struct sembuf sops = {0,
                          0,
                          0
                         };

    semop(semid, &sops, 1);
}

int main(int argc, char **argv)
{
    key_t  key;
    int    shmid, semid;
    char   *shm;
    char   msg[100];
    char   i;

    key = ftok("/", 0);
    shmid = shmget(key, SEGSIZE, 0);

    if (shmid == -1)
    {
        printf("create shared memory error\n");
        return -1;
    }

    semid = new_sem(key);

    for (i = 0;i < 3;i ++)
    {
        sleep(2);
        wait_v(semid);
        printf("Message geted is: %s \n",shm + 1);
        out_time();
    }

    shmdt(shm);

    return 0;

}

server.c文件

#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>
#include<stdio.h>
#include<unistd.h>

union semum
{
	int	val;
	struct semid_ds	*buf;
	unsigned short *array;
};


#define SEGSIZE   1024
#define READTIME  1


/* 创建信号量 */
int sem_creat(key_t  key)
{
		union semun sem;
    int         semid;
    sem.val = 0;
    semid = semget(key, 1, IPC_CREAT | 0666);

    if (semid == -1)
    {
        printf("Create semaphore error\n");
        exit(-1);
    }

    semctl(semid, 0, SETVAL, sem);

    return semid;
}

/* 删除信号量*/
int del_sem(int semid)
{
    union semun  sem;
    sem.val = 0;
    semctl(semid, 0, IPC_RMID, sem);
}

/* 信号量的P操作,使得信号量的值加1 */
int p(int semid)
{
    struct sembuf sops = {0,
                          +1,
                          IPC_NOWAIT
                         };

    return (semop(semid, &sops, 1));
}

/* 信号量的v操作,使得信号量的值减1 */
int v(int semid)
{
    struct sembuf sops = {0,
                          -1,
                          IPC_NOWAIT
                         };

    return (semop(semid, &sops, 1));
}

/* server主程序 */
int main(int argc, char **argv)
{
    key_t            key;
    int              shmid, semid;
    char             *shm;
    char             msg[7] = "-data-";
    char             i;
    struct semid_ds  buf;

    key = ftok("/", 0);
    shmid = shmget(key, SEGSIZE, IPC_CREAT|0604);
    
    if shmid == -1)
    {
        printf(" create shared memory error\n");
        return -1;
    }

    shm = (char *)shmat(shmid, 0, 0);
    if (-1 == (int)shm)
    {
        printf(" attach shared memory error\n");
        return -1;
    }

    semid = sem_creat(key);
    for (i = 0; i <= 3; i++)
    {
        sleep(1);
        p(semid);
        sleep(READTIME);
        msg[5] = '0' + i;
        memcpy(shm,msg,sizeof(msg));
        sleep(58);
        v(semid);
    }

    shmdt(shm);

    shmctl(shmid,IPC_RMID,&buf);

    del_sem(semid);

    return 0;
}

3. android通过ion内存来实现父进程和子进程之间的内存共享(不知道非父子进程之间怎么用ion内存)


4. 通过mmap实现()



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值