共享内存的读写

首先我们需要一个 shm_com.h

#ifndef _SHM_COM_H_
#define _SHM_COM_H_

#define TEXT_SZ 2048

struct shared_use_st {
    int written_by_you;
    char some_text[TEXT_SZ];
};

#endif /* _SHM_COM_H  */

然后是 shm1.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "shm_com.h"

int main() {
    int running = 1;
    void* shared_memory = (void *)0;
    struct shared_use_st* shared_stuff;
    int shmid;

    srand((unsigned int)getpid());
    shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    shared_memory = shmat(shmid, (void *)0, 0);
    if (shared_memory == (void *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    printf("Memory attached at %X\n", (int)shared_memory);

    shared_stuff = (struct shared_use_st *)shared_memory;
    shared_stuff->written_by_you = 0;
    while (running) {
        if (shared_stuff->written_by_you) {
            printf("You wrote: %s", shared_stuff->some_text);
            sleep(rand() % 4);
            shared_stuff->written_by_you = 0;
            if (strncmp(shared_stuff->some_text, "end", 3) == 0) {
                running = 0;
            }
        }
    }

    if (shmdt(shared_memory) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    if (shmctl(shmid, IPC_RMID, 0) == -1) {
        perror("shmctl");
        exit(EXIT_FAILURE);
    }
   
    return 0;
}

然后是 shm2.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "shm_com.h"

int main() {
    int running = 1;
    void* shared_memory = (void *)0;
    struct shared_use_st* shared_stuff;
    char buffer[TEXT_SZ];
    
    int shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    shared_memory = shmat(shmid, (void *)0, 0);
    if (shared_memory == (void *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    printf("Memory attached at %X\n", (int)shared_memory);

    shared_stuff = (struct shared_use_st *)shared_memory;

    while (running) {
        while (shared_stuff->written_by_you == 1) {
            sleep(1);
            printf("waiting for client...\n");
        }
        printf("Enter some text: ");
        fgets(buffer, TEXT_SZ, stdin);
        strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
        shared_stuff->written_by_you = 1;

        if (strncmp(buffer, "end", 3) == 0) {
            running = 0;
        }
    }

    if (shmdt(shared_memory) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }
    
    return 0;
}

编译一下

g++ -g -Wall shm1.cpp -o shm1.exe
g++ -g -Wall shm2.cpp -o shm2.exe

就可以运行了

——————————————————————–

2013-03-28 20:04:11 update:注意 shmdt 和 shmctl 两种方式结束共享内存是不同的,shmdt 只是当前进程脱离共享内存,不对内存造成其他影响,而 shmctl 方式是删除这片内存,那样的话,其他的进程就再也无法 attach 这片内存了(已经 attach 上的可以继续)用,但是系统会把这片内存标记为 dest

Leave a Reply

Your email address will not be published. Required fields are marked *