进程通信之共享内存篇

Posted 我有一壶酒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程通信之共享内存篇相关的知识,希望对你有一定的参考价值。

共享内存原理示意图

 

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

 

以上是关于进程通信之共享内存篇的主要内容,如果未能解决你的问题,请参考以下文章

Python进程间通信之共享内存

linux进程间通信之System V共享内存详解及代码示例

Android之Binder通信篇

linux进程间通信之Posix共享内存用法详解及代码举例

linux之进程通信——共享内存

进程间通信之共享内存