共有メモリの概要

共有メモリとの起源の研究のための「Linuxの高性能サーバ、」チャットサーバのコードを読んで理解する共有メモリ!しかし、実際には、我々はめったに約束していない、サーバー側を行う每一个客户连接分配一个进程来处理相应的写或者读事件アプローチを。彼は、親共有メモリにサーバーを作成し、その管理共有メモリの対応する位置に書き込まれるクライアントに接続されたときに、良好で、各サブプロセスのクライアント・データを処理するためのプロセスをフォークし、双方向通信パイプライン検査を使用します信号は、クライアントが接続を切断する一連の信号処理により、切断親クライアントは、回復プロセスに対応します。メインプログラムは、共有メモリを使用するのは簡単ですし、共有メモリの同期を必要としません。
PS。菜鸡想吐槽小さな例を通じて予約していないここでは、共有メモリの面で単純なアプリケーションですが、直接に共有メモリを使用することに、なぜ私は理解していないepoll+多进程+信号サーバー。このように、共有メモリの話をする、それは読者がほぼ400のコードにかむことができます!涙に人の心を見てください!彼は唯一の言っていない共有メモリAPIのいくつかを紹介しているような彼の原則のいくつか!


  • 共有メモリブリーフ

単純な話への共有メモリは、迅速なIPCメカニズムを達成することである、と今、私たちは、IPCは、私が知っていることを言うことを、達成するための方法を考えます:

  • パイプは、名前付きパイプで通信することができ、異なるプロセス間の匿名パイプは、親と子の間の通信を実現することができます。
  • メッセージキューは、私は実現するためにカーネルによって維持されたメッセージのリストのように、もっと身近です。
  • 共有メモリ。

これらは、これまで私は、IPCメカニズム、なぜ高速な共有メモリを知っていますか?最初の3のために、通過:
数据从文件写到进程控制的内存- > 操作- > 将数据cp到内核- > 通知对话的进程进行读取- > 对端进程从内核读取- > 操作...
<これらのステップは、システムの多くは、操作を完了するために呼び出す必要が効率が低下、システムリソースを消費することに注意してください!>
共有メモリ?
そうでない場合には、メモリ空間を共有しました。
创建共享内存对象(これは、単に新しいファイルという意味) - > 指定文件的控制空间大小(私たちは確かに、共有メモリを作成し、それを一定の範囲を持っている必要があります!) - > 通过映射,将创建好的共享内存对象映射到内存页表、物理メモリ内の対応する共有メモリ・セグメントと、この時間を、次のように(画的是大概的映射机制,由于认识有限,不敢做过多描述,有披露的话,还请指出):

ここに画像を挿入説明
だから、私たちはなぜ、共有メモリに高速理解することができます!異なるプロセスが動作するメモリのこのセクションに直接データを読み書きする際に、システムコールの一部を除去する、プロセス、および便利間の高速通信。
異なるプロセスの同期を限定する対応する共有メモリ保護のロック機構がないので、それは、メモリ読み取りまたは変更操作の同じセクションに複数のプロセスを含むのでもちろん、欠陥が存在しなければなりません。このため、プロセス間の同期を達成するために、共有メモリのロックや条件などの他のプロセス間通信機構に沿って使用します、!

。psの不可解シェア、一連の質問を作成、共有メモリを学ぶ:
プロセス・ブロック(PCB)とは何ですか?
プロセスのアドレス空間とは何ですか?
メモリのページテーブルは何ですか?

より多くの考えは、私は学校にこの共有メモリを終えることができなかった場合は、本当に私は、考えることはできません。情報へのアクセスを通じ、単純に次のような結論に来ます。

処理ブロックは、記録プロセスは、カーネル状態データ構造情報および資源、すなわちtask_structあります。
プロセスのユーザ空間仮想アドレス空間、プロセス、4GBのサイズ!もっと知りたい場合は、私がお勧めします。この記事の
物事の仮想および物理メモリに一致するようにメモリのページテーブルを。

下に取得する場合まず、単純な理解を作る、それは本当にアップChaogang!


  • 共有メモリの使用

共享内存的POSIX方法

<sys/mman.h>
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
int munmap(void* start,size_t length);

ここでは、小さなサンプルアプリケーションです:
二つのプロセス間で同期されていないので、実行は、メモリ内のダーティリード値になります。共有メモリを作成するプロセスを理解するための鍵。共有メモリの場所を見つける直接読み取り処理はMMAPで読み取ることができ、そしてあまりにも多くの問題を作成しませんでした!

#include <iostream>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<sys/mman.h>
#include<memory.h>
#include"socketfd.h"

using namespace std ;
#define SHARED_SIZE 120
const char*shm_name = "/myshm" ;
char* shm_add ;
void handler(int arg) ;

int main()
{

    cout << "创建共享内存" << endl ;
    //*****使用shm_open 来创建共享内存的对象,使用方法和open相同
    int sh = shm_open(shm_name, O_CREAT|O_RDWR|O_TRUNC, 0677)  ;

    //*****指定共享内存对象控制的空间大小
    ftruncate(sh, SHARED_SIZE) ;
    
    //将所创建的共享内存对象映射到内存页上
    //第一个参数NULL,表示让操作系统决定要关联的共享内存地址
    //第二个参数是共享内存的大小
    //第三个参数指定要要进行的操作,写数据,读数据.....
   //第四个参数指定改段内存是共享的,map_shared
   //sh文件描述符
   //*****被映射内容的起点位置,从共享内存0开始
    char* a = (char*)mmap(NULL, SHARED_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, sh, 0);
    memset(a, SHARED_SIZE, '\0') ;
    shm_add = a ;
    assert(a != MAP_FAILED) ;
    //*****关掉文件
    close(sh) ;
    //往共享内存中写数据
    const char* shm_data = "hello_world!" ;
    int len = strlen(shm_data) ;
    signal(SIGINT, handler) ;

    cout <<"写数据:"<<"" ;
    int i =0 ;
    for(;;)
    {
        memcpy(a, shm_data+i, len) ;
        cout <<*a<<endl ; 
        sleep(1) ;
        i++ ;
        if(i == len)break ;
    }
    //******分离进程与共享内存对象
    munmap(shm_add, SHARED_SIZE) ;
}

void handler(int arg)
{
    munmap(shm_add, SHARED_SIZE) ;
}
#include <iostream>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<sys/mman.h>
#include<memory.h>
#include"socketfd.h"
using namespace std ;
#define SHARED_SIZE 120
const char*shm_name = "/myshm" ;
char* shm_add ;
void handler(int arg) ;
int main(int argc, char**argv)
{

    int sh = shm_open(shm_name, O_RDWR, 0677)  ;
    
    char* a = (char*)mmap(NULL, SHARED_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, sh, 0);
    signal(SIGINT, handler) ;
    shm_add = a ;
    int i = 0 ;
    cout << "读数据:" << endl ;
    while(1)
    {
        cout << *(a+i) <<endl  ;
        i++ ;
        sleep(1) ;
    }
    munmap(shm_add, SHARED_SIZE) ;
    return 0;
}

void handler(int arg)
{
    munmap(shm_add, SHARED_SIZE) ;
}
//记得加指定连接选项 -lrt
 g++ mmap.cpp -o write -lrt
 g++ mmap_read.cpp -o read -lrt

これらは、一時的にいくつかの小さな和である意識の高まりとともに、その後、我々はいくつかの欠点が追加されます!

下面是另一种方法

参考ブログ

おすすめ

転載: blog.csdn.net/qq_41681241/article/details/88910562