• 进程通信之共享内存篇


    共享内存原理示意图

    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
    ", 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
    ", shm_addr);
            }
            system("ipcs -m");
    
            /* 通过检查在共享内存的头部是否是标志字符串WROTE来确认
               父进程已经向共享内存写入有效数据 */
            while( strncmp(shm_addr, flag, strlen(flag)) )
            {
                printf("Child: Wait for enable data...
    ");
                sleep(5);
            }
    
            /* 获取共享内存的有效数据并显示 */
            strcpy(buff, shm_addr + strlen(flag));
            printf("Child: Shared-memory : %s 
    ",buff);
    
            /* 解除共享内存映射 */
            if((shmdt(shm_addr)) < 0)
            {
                perror("shmdt");
                exit(1);
            }
            else
            {
                printf("Child: Deattach shared-memory
    ");
            }
            system("ipcs -m");
    
            /* 删除共享内存 */
            if(shmctl(shmid, IPC_RMID, NULL) == -1)
            {
                perror("Child: shmctl(IPC_RMID) 
    ");
                exit(1);
            }
            else
            {
                printf("Delete shared-memory
    ");
            }
    
            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
    ", shm_addr);
            }
    
            sleep(1);
            printf("
     Input some string: 
    ");
            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
    ");
            }
            system("ipcs -m");
    
            waitpid(pid, NULL, 0);
            printf("Finished
    ");
        }
        return 0;
    }
  • 相关阅读:
    Unix环境中的刷新
    C++ 的类型转换方法
    系统对信号的三种处理方式
    进程原语与线程原语的比较
    C和C++对带空参数列表的函数声明的不同处理
    函数指针
    字符串化的预处理器特征
    调试技巧
    信号产生的条件
    结构体大小问题
  • 原文地址:https://www.cnblogs.com/yihujiu/p/5598086.html
Copyright © 2020-2023  润新知