Linux 共享内存例子

来源:互联网 发布:小学生作文用什么软件 编辑:程序博客网 时间:2024/06/04 06:18

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 1union 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{intval;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 0
原创粉丝点击