mmap(内存映射)和shm(共享存储)



mmap(内存映射)和shm(共享存储):
1、mmap是在磁盘上建立一个文件,每个进程地址空间中开辟出一块空间进行映射。
而对于shm而言,shm每个进程最终会映射到同一块物理内存。
shm保存在物理内存,这样读写的速度要比磁盘要快,但是存储量不是特别大。
2、相对于shm来说,mmap更加简单,调用更加方便,所以这也是大家都喜欢用的原因。
3、另外mmap有一个好处是当机器重启,因为mmap把文件保存在磁盘上,这个文件还保存了操作系统同步的映像,所以mmap不会丢失,但是shmget就会丢失


$ -> g++ shmread.cpp -o read -lpthread
$ -> g++ shmwrite.cpp -o write -lpthread

$ -> ./read
READ PROCESS:
            OK
READ PROCESS:
            GOOD
READ PROCESS:
            BYE
READ PROCESS:
            exit

$ -> ./write
WRITE PROCESS:
OK
WRITE PROCESS:
GOOD
WRITE PROCESS:
BYE
WRITE PROCESS:
exit


(1)shminfo.h

#ifndef SHARE_MEMORY_INFO_H
#define SHARE_MEMORY_INFO_H

#include <stdio.h>

#define SHM_MODE  0666
#define SEM_NAME "/shmtest_sem"
#define CHECK_ERROR(flag, funname) do {         \
        bool tmp = (flag);                      \
        if (tmp) {                              \
            printf("%s return error", funname); \
        }                                       \
} while (0)

struct shm_data
{
    char data[32];
    int len;
};

#endif
(2)shmread.cpp
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "shminfo.h"
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>

int main()
{
    key_t key;
    shm_data *shm = NULL;    // share info
    sem_t *sem = NULL;
    int shmid;

    sem = sem_open(SEM_NAME, O_CREAT, SHM_MODE, 1);
    CHECK_ERROR(SEM_FAILED == sem, "sem_open");

    key =ftok(".", 1);
    CHECK_ERROR(-1 == key, "ftok");

    shmid = shmget(key, sizeof(shm_data), SHM_MODE | IPC_CREAT);
    CHECK_ERROR(-1 == shmid, "shmget");

    shm = (shm_data *)shmat(shmid, NULL, 0);
    CHECK_ERROR((shm_data *)-1 == shm, "shmat");

    for (;;) {
        CHECK_ERROR(-1 == sem_wait(sem), "sem_wait");
        printf("READ PROCESS:\n            %s", shm->data);
        sleep(rand()%5);
        if (0 == strcmp(shm->data, "exit\n")) {
            printf("goodbye read\n");
            fflush(stdout);
            sem_post(sem);
            break;
        }
        sem_post(sem);
        sleep(rand()%5);
    }

    if (NULL != sem) {
        CHECK_ERROR(-1 == sem_close(sem), "sem_close");
        CHECK_ERROR(-1 == sem_unlink(SEM_NAME), "sem_unlink"); // sem instance stores in "/dev/shm/", recreated will fail, if no unlink
    }

    if (NULL != shm) {
        CHECK_ERROR(-1 == shmdt(shm), "shmdt");                 // detach share memory from current process
        CHECK_ERROR(-1 == shmctl(shmid, IPC_RMID, 0), "shmctl");// delete share memory
    }

    return 0;
}
(3)shmwrite.cpp
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "shminfo.h"
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>

int main()
{
    key_t key;
    shm_data *shm = NULL;    // share info
    sem_t *sem = NULL;
    int shmid;

    sem = sem_open(SEM_NAME, O_CREAT, SHM_MODE, 1);
    CHECK_ERROR(SEM_FAILED == sem, "sem_open");

    key =ftok(".", 1);
    CHECK_ERROR(-1 == key, "ftok");

    shmid = shmget(key, sizeof(shm_data), SHM_MODE | IPC_CREAT);
    CHECK_ERROR(-1 == shmid, "shmget");

    shm = (shm_data *)shmat(shmid, NULL, 0);
    CHECK_ERROR((shm_data *)-1 == shm, "shmat");

    for (;;) {
        CHECK_ERROR(-1 == sem_wait(sem), "sem_wait");
        printf("WRITE PROCESS:\n");
        fgets(shm->data, 32, stdin);
        if (0 == strcmp(shm->data, "exit\n")) {
            printf("goodbye write\n");
            fflush(stdout);
            sem_post(sem);
            break;
        }
        sem_post(sem);
        sleep(rand()%6);
    }

    if (NULL != sem) {
        sem_close(sem);
    }

    if (NULL != shm) {
        CHECK_ERROR(-1 == shmdt(shm), "shmdt");                 // detach share memory from current process
    }

    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值