进程通信之共享内存篇

共享内存原理示意图

 

shmget函数语法:

shmat函数语法

shmdt函数语法

 

代码分析:

/* shmem.c */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 2048

int main()
{
    pid_t pid;
    int shmid;
    char* shm_addr;
    char flag[] = "WROTE";
    char buff[BUFFER_SIZE];

    /* 创建共享内存 */
    if((shmid = shmget(IPC_PRIVATE, BUFFER_SIZE, 0666)) < 0)
    {
        perror("shmget");
        exit(1);
    }
    else
    {
        printf("Create share-memory: %d\n", shmid);
    }

    /* 显示共享内存情况 */
    system("ipcs -m");

    pid = fork();
    if(pid == -1)
    {
        perror("fork");
        exit(1);
    }
    else 
        if( pid == 0 )    /* 子进程处理 */
       {
        /* 映射共享内存 */
        if((shm_addr = shmat(shmid, 0, 0)) == (void*)-1)
        {
            perror("Child: shmat");
            exit(1);
        }
        else
        {
            printf("Child: Attach shared-memory: %p\n", shm_addr);
        }
        system("ipcs -m");

        /* 通过检查在共享内存的头部是否是标志字符串WROTE来确认
           父进程已经向共享内存写入有效数据 */
        while( strncmp(shm_addr, flag, strlen(flag)) )
        {
            printf("Child: Wait for enable data...\n");
            sleep(5);
        }

        /* 获取共享内存的有效数据并显示 */
        strcpy(buff, shm_addr + strlen(flag));
        printf("Child: Shared-memory : %s \n",buff);

        /* 解除共享内存映射 */
        if((shmdt(shm_addr)) < 0)
        {
            perror("shmdt");
            exit(1);
        }
        else
        {
            printf("Child: Deattach shared-memory\n");
        }
        system("ipcs -m");

        /* 删除共享内存 */
        if(shmctl(shmid, IPC_RMID, NULL) == -1)
        {
            perror("Child: shmctl(IPC_RMID) \n");
            exit(1);
        }
        else
        {
            printf("Delete shared-memory\n");
        }

        system("ipcs -m");
    }
    else    /* 父进程处理 */
    {
        /* 映射共享内存 */
        if((shm_addr = shmat(shmid, 0, 0)) == (void*)-1)
        {
            perror("Parent: shmat");
            exit(1);
        }
        else
        {
            printf("Parent: Attach shared-memory: %p\n", shm_addr);
        }

        sleep(1);
        printf("\n Input some string: \n");
        fgets(buff, BUFFER_SIZE, stdin);
        strncpy(shm_addr + strlen(flag), buff, strlen(buff));
        strncpy(shm_addr, flag, strlen(flag));

        /* 解除共享内存映射 */
        if((shmdt(shm_addr)) < 0)
        {
            perror("Parent: shmdt");
            exit(1);
        }
        else
        {
            printf("Parent: Deattach shared-memory\n");
        }
        system("ipcs -m");

        waitpid(pid, NULL, 0);
        printf("Finished\n");
    }
    return 0;
}

 

posted @ 2016-06-19 15:01  我有一壶酒  阅读(354)  评论(0编辑  收藏  举报