Linux 基于IPC机制实现进程间的共享内存处理

今天学习了相关于IPC(InterProcess Communication ,进程间通信)的相关知识。就做个笔记,一来让大家检查一下我的理解方面是不是有错误,二来也为了能让更多的博友们了解到相关的知识吧。


IPC的种类


IPC 的种类,一般来说下面两种使用的较多:
- 共享“内存”
- 消息传递


下来我们就分别的介绍一下相关的信息吧。

共享内存


字面意思的理解是采用共享一块计算机中的内存空间来实现的进程之间的通信的一种方式。也就是说这块内存区域驻留在生成共享内存段进程的地址空间。(是存在于用户态内核的区域的)其他进程通过对此块空间的数据进行读写操作来完成相应的通信所需。
好处:进程的通信会非常的快;
缺点:由于不同进程可以对这块共享内存进行操作,就有可能导致数据的读写冲突,或者得到的数据有可能会不一致!


下面是一个实现了进程之间通过共享内存的方式实现进程通信的一个小例子:
首先我们先普及一下相关的函数的具体的细节:
前提是记得引入相关的头文件哦(代码中已标出)

//通过系统调用获得一个共享内存区域
shmget(IPC_PRIVATE,                //生成一个新的共享内存片段
                 size,             //共享内存区的大小
                S_IRUSR | S_IWUSR  //读写操作共享内存区
                ); int             //该函数返回一个整形值

//通过系统调用将要访问内存空间的进程加入到共享内存空间的地址
shmat(
        id,          //希望加入的内存片段的整数标识值
        NULL,        //NULL代表操作系统为用户选择共享内存位置
        0            //0代表可以对共享内存进行读和写的操作
        ); char*     //该函数将返回一个指针,指向共享内存区的内存的初始位置
//将要操作的数据写入到共享内存的空间中
sprintf(
        shared_memory,    //写入数据的目的地的指针
        string            //写入的数据,可以通过变换写入自己的想要的数据类型
        );
//分离出共享内存区域
shmdt(shared_memory);
//借助系统调用,把标志IPC_RMID和共享内存段的标识符一起做为参数,移除!
shmctl();
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include<sys/types.h>
// use for InterProcess Communication
#include<sys/shm.h>
#include<sys/stat.h>
#include<sys/wait.h>
// the global const variable
int value = 5 ;

int main()
{
    pid_t pid ;



    /**
            begin the interprocess communication system call
    */
    const int Size = 2048 ;
    int segment_id =  shmget(IPC_PRIVATE , Size , S_IRUSR | S_IWUSR) ;
    char* shared_memory = (char*) shmat(segment_id, NULL, 0) ;
    pid = fork();


    if(pid == 0 ){
        value += 15 ;
        sprintf(shared_memory,"%d" , value );
        printf("Value from Children : %d\n",value) ;
        /**almostly we will add the return statement at the end of the child process to make sure the code return correctly.*/
        return 0;
       /** printf("Child  value : %d",value);*/
    }else if (pid > 0 ){
        /** wait all the child end ,then notify the parent process */
        wait(NULL);
        /**sprintf(shared_memory,"%d" , value );*/
    }

    /** check the result of the shared_memory */
    printf("Value from Parent  : %s" , shared_memory) ;

    /**to make sure deattach the shared_memory*/
    shmdt(shared_memory) ;

    /**remove the shared memory segment also */
    shmctl(segment_id ,IPC_RMID , NULL) ;

    return 0;
}

程序运行的结果如下:
Linux 基于IPC机制实现进程间的共享内存处理


消息传递方式


底层是在内核态创建一个缓冲区,需要进行通信的进程将数据写入缓冲区,然后对方借助系统调用的方式获取到数据,由此来实现进程之间的通信的方法!主要实现send方法和receive方法即可。
这种方式实现的思路比较简单,适用于数据量较小的通信。而且没有类似于共享内存方式的冲突问题发生。但是速度相对而言比较的慢,有利有弊吧!


内部的实现同样也有两种:

  • 直接的消息传递
  • 间接的消息传递(也成为邮箱模式)

直接消息传递是指接收和发送消息的时候都对相关的进程进行指定。
而间接的消息传递是指将消息都发送到一个“公共邮箱”,大家都可以进行数据的获取!前者比较适合于一对一的模式,后者则适用于一对多的通信。


总结


对于进程间的通信,里面可谓是有很大的学问。上面介绍的也不过是冰山一角而已。如果您发现文章中有不恰当的地方,欢迎指正。谢谢!

上一篇:java NIO


下一篇:Skype For Business 2015实战系列14:创建Office Web App服务器场