进程通信之共享内存篇

共享内存原理示意图

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;
}
时间: 2024-08-29 02:31:00

进程通信之共享内存篇的相关文章

进程通信之共享内存

共享内存 共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自

linux 进程通信之 共享内存

共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容. 关于共享内存使用的API key_t ftok(const char *pathname, int proj_id); #在IPC中,我们经常用一个 key_t 的值来创建或者打开 信号量,共享内存和消息队列.这个 key_t 就是由ftok函数产生的. pathname:指定的文件名,该文件必须是存在而且可以访问 proj_

Linux 进程通信(共享内存区)

共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段). 如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映像到自己的私有地址空间中. 如果一个进程更新了段中的数据,其他进程也立即会看到更新. 由一个进程创建的段,也可以由另一个进程读写. 每个进程都把它自己对共享内存的映像放入自己的地址空间. 创建共享内存区 int shmget(key_t key,size_t size,int shm-flg); 参数key既可以是IPC_PRIVATE(IPC_PRIVATE表示让

进程通信(共享内存)

共享内存: 用于进程间数据传输,是最高效的,并不提供同步,互斥  shm.h:   1 #include<stdio.h>   2 #include<stdlib.h>   3 #include<sys/ipc.h>   4 #include<sys/shm.h>   5 #include<string.h>   6 #include<sys/wait.h>   7 #include <unistd.h>   8    9

linux进程通信之共享内存

共享内存同意两个或多个进程共享一给定的存储区,由于数据不须要来回复制,所以是最快的一种进程间通信机制.共享内存能够通过mmap()映射普通文件(特殊情况下还能够採用匿名映射)机制实现,也能够通过系统V共享内存机制实现.应用接口和原理非常easy,内部机制复杂.为了实现更安全通信,往往还与信号量等同步机制共同使用.以下主要介绍系统V共享内存机制,主要用到的系统API包含: 1.shmget函数:获得一个共享内存标识符. int shmget(key_t key, size_t size, int 

linux进程间的通信(C): 共享内存

一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的一种非常有效的方式. 大多数的共享内存的实现, 都把由不同进程之间共享的内存安排为同一段物理内存. 共享内存是由IPC为进程创建一个特殊的地址范围, 它将出现在该进程的地址空间中. 其他进程可以将同一段共享内存连接它们自己的地址空间中. 所有进程都可以访问共享内存中的地址, 就好像它们是由mallo

linux进程间的通信之 共享内存

一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的一种非常有效的方式. 大多数的共享内存的实现, 都把由不同进程之间共享的内存安排为同一段物理内存. 共享内存是由IPC为进程创建一个特殊的地址范围, 它将出现在该进程的地址空间中. 其他进程可以将同一段共享内存连接它们自己的地址空间中. 所有进程都可以访问共享内存中的地址, 就好像它们是由mallo

信号,信号量,锁,条件变量,消息通信,共享内存,RPC (一)

在实际项目当中,经常需要把一个功能分成多个子模块实现.那么,这些子模块之间该如何关联起来呢?静态地看,模块可以看作一组完成相同功能的函数:而动态地看,模块可以是一个独立的进程.线程或者一个中断服务或者信号服务例程.根据不同的具体业务实现,它们之间可能是静态调用.动态互斥.同步.唤醒等关系.静态的调用很好实现,上层的函数调用底层的函数即可.那么,动态互斥.同步.唤醒等关系,又该如何实现呢?这就设计到我们将要讨论的信号.进程间消息通信.共享内存.线程互斥同步条件变量.RPC等手段.下面就按照Linu

【网络编程基础】Linux下进程通信方式(共享内存,管道,消息队列,Socket)

在网络课程中,有讲到Socket编程,对于tcp讲解的环节,为了加深理解,自己写了Linux下进程Socket通信,在学习的过程中,又接触到了其它的几种方式.记录一下. 管道通信(匿名,有名) 管道通信,在一个进程之中,只能单一的对其写或者是读,而不可以及执行写操作又执行读操作.这一点,我们可以将其想象成我们的水管,分别连着不同的两端,在有水流的时候,一端只能进行输入,另一端只能进行输出,而不可以同时输入和输出. 管道又分为有名管道和匿名管道,两者的区别在于对于匿名管道,其只能在具有亲缘关系的父