C++
 Computer >> コンピューター >  >> プログラミング >> C++

共有メモリを使ったプロセス間通信(IPC)の仕組みと実装例

共有メモリとは

共有メモリとは、2つ以上のプロセス間で共有されるメモリ領域のことです。では、なぜメモリを共有したり、何らかの通信手段が必要になったりするのでしょうか。

繰り返しになりますが、各プロセスはそれぞれ独立したアドレス空間を持っています。あるプロセスが、自分のアドレス空間内の情報を使って他のプロセスと通信したい場合、IPC(プロセス間通信)の技術を利用するしかありません。なお、通信は親子関係にある関連プロセス同士でも、まったく無関係なプロセス同士でも行うことができます。

通常、関連するプロセス間の通信にはパイプ(Pipe)や名前付きパイプ(Named Pipe)が使われます。一方、無関係なプロセス間(たとえば、あるターミナルで動作するプロセスと別のターミナルで動作するプロセス)の通信には、名前付きパイプのほか、共有メモリやメッセージキューといった代表的なIPC技術が利用されます。

これまでの記事でパイプと名前付きパイプというIPC技術を取り上げてきました。ここからは、残りのIPC技術である共有メモリ、メッセージキュー、セマフォ、シグナル、メモリマッピングについて解説していきます。

共有メモリを使ったプロセス間通信(IPC)の仕組みと実装例

共有メモリで使用するシステムコール

2つ以上のプロセス間で通信を行うために共有メモリを使用することはすでに説明しましたが、共有メモリを実際に使う前に、どのようなシステムコールを呼び出す必要があるのかを確認しておきましょう。

  • 共有メモリセグメントを新規に作成する、または既存の共有メモリセグメントを取得する(shmget())
  • プロセスを作成済みの共有メモリセグメントにアタッチする(shmat())
  • プロセスをアタッチ済みの共有メモリセグメントからデタッチする(shmdt())
  • 共有メモリセグメントに対する制御操作を行う(shmctl())

書き込み側と読み取り側のプロセス

ここでは2つのプロセスを作成します。片方はデータを書き込み、もう片方はデータを読み取ります。共有メモリを使って、ライター(書き込み側)プロセスとリーダー(読み取り側)プロセスがどのように動作するのかを見ていきましょう。

書き込み側(ライター)プログラムの例

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
using namespace std;
main() {
    key_t my_key = ftok("shmfile",65); // ftok関数は一意なキーを生成するために使用
    int shmid = shmget(my_key,1024,0666|IPC_CREAT); // shmgetは識別子をshmidに返す
    char *str = (char*) shmat(shmid,(void*)0,0); // shmatで共有メモリに接続
    cout<<"Write Data : ";
    fgets(str, 50, stdin);
    printf("Data written in memory: %s\n",str);
    // 共有メモリからデタッチ
    shmdt(str);
}

読み取り側(リーダー)プログラムの例

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
using namespace std;
main() {
    key_t my_key = ftok("shmfile",65); // ftok関数は一意なキーを生成するために使用
    int shmid = shmget(my_key,1024,0666|IPC_CREAT); // shmgetは識別子をshmidに返す
    char *str = (char*) shmat(shmid,(void*)0,0); // shmatで共有メモリに接続
    printf("Data read from memory: %s\n",str);
    shmdt(str);
    shmctl(shmid,IPC_RMID,NULL); // 共有メモリを破棄
}

実行結果

共有メモリを使ったプロセス間通信(IPC)の仕組みと実装例

  1. Google Chromeのメモリ使用量が多い?メモリリークの原因と対処法を徹底解説

    Google Chromeは軽快な動作とシンプルなインターフェースで、世界中で愛用されているブラウザです。筆者もその圧倒的なスピード感が気に入っており、アドオンが多く動作の重いFirefoxや、どうしても遅くなりがちなInternet ExplorerよりもChromeを選んできました。Microsoft EdgeはIEよりかなり高速になりましたが、GmailやGoogleドライブなどGoogleサービスを多用する身としては、やはりChromeが一番しっくりきます。ちなみに、新エンジン「Quantum」を搭載したFirefoxはChromeより速いとも言われており、乗り換えを本気で検討したこと

  2. 【保存版】Windows 10でIRQL_NOT_LESS_OR_EQUALエラー(0x0000000A)を解決する8つの方法

    IRQL_NOT_LESS_OR_EQUALエラーとは? バグチェックコード0x0000000Aを伴うIRQL_NOT_LESS_OR_EQUALエラーは、カーネルモードのドライバーが、高い割り込み要求レベル(IRQL)の状態で、無効なアドレスにあるページング可能なメモリにアクセスしたことを示しています。簡単に言えば、ドライバーがアクセス権限を持たないメモリアドレスへアクセスしようとしたことが原因です。 ユーザーアプリケーションでこの問題が発生した場合は「アクセス違反」のエラーメッセージが表示されますが、カーネルモードで発生するとSTOPエラーコード0x0000000Aが生成され、ブルースクリ