Inter-process-communication-shared-memory

提供:Dev Guides
移動先:案内検索

共有メモリ

共有メモリは、2つ以上のプロセス間で共有されるメモリです。 ただし、メモリやその他の通信手段を共有する必要があるのはなぜですか?

繰り返しますが、各プロセスには独自のアドレス空間があります。プロセスが独自のアドレス空間から他のプロセスと情報をやり取りしたい場合は、IPC(プロセス間通信)技術でのみ可能です。 すでに認識しているように、通信は、関連するプロセスと無関係のプロセスの間で行われます。

通常、相互に関連するプロセス通信は、パイプまたは名前付きパイプを使用して実行されます。 関連のないプロセス(たとえば、ある端末で実行中のプロセスと別の端末で実行中の別のプロセス)の通信は、名前付きパイプを使用するか、共有メモリおよびメッセージキューの一般的なIPC技術を使用して実行できます。

パイプと名前付きパイプのIPCテクニックを見てきましたが、残りのIPCテクニック、つまり共有メモリ、メッセージキュー、セマフォ、シグナル、およびメモリマッピングを知る時が来ました。

この章では、共有メモリについてすべてを説明します。

共有メモリ

私たちは2つ以上のプロセス間で通信するために共有メモリを使用することを知っていますが、共有メモリを使用する前にシステムコールで何をする必要があるかを見てみましょう-

  • 共有メモリセグメントを作成するか、作成済みの共有メモリセグメントを使用します(shmget())
  • 作成済みの共有メモリセグメントにプロセスをアタッチします(shmat())
  • すでにアタッチされている共有メモリセグメントからプロセスをデタッチします(shmdt())
  • 共有メモリセグメントでの操作の制御(shmctl())

共有メモリに関連するシステムコールのいくつかの詳細を見てみましょう。

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg)

上記のシステムコールは、System V共有メモリセグメントを作成または割り当てます。 渡す必要がある引数は次のとおりです-

  • 最初の引数、キー*は共有メモリセグメントを認識します。 キーは、任意の値でも、ライブラリ関数ftok()から派生した値でもかまいません。 キーはIPC_PRIVATE、つまり、サーバーおよびクライアント(親子関係)としてプロセスを実行する、つまり相互に関連するプロセス通信でもあります。 クライアントがこのキーで共有メモリを使用する場合、サーバーの子プロセスである必要があります。 また、親が共有メモリを取得した後に、子プロセスを作成する必要があります。
*2番目の引数、size* は、PAGE_SIZEの倍数に丸められた共有メモリセグメントのサイズです。
*3番目の引数shmflg* は、IPC_CREAT(新しいセグメントの作成)やIPC_EXCL(IPC_CREATと併用して新しいセグメントを作成し、セグメントが既に存在する場合は呼び出しが失敗する)などの必要な共有メモリフラグを指定します。 許可も渡す必要があります。

-権限の詳細については、前のセクションを参照してください。

この呼び出しは、成功した場合は有効な共有メモリ識別子(共有メモリの以降の呼び出しに使用)を返し、失敗した場合は-1を返します。 失敗の原因を知るには、errno変数またはperror()関数で確認してください。

#include <sys/types.h>
#include <sys/shm.h>

void *shmat(int shmid, const void* shmaddr, int shmflg)

上記のシステムコールは、System V共有メモリセグメントの共有メモリ操作を実行します。つまり、共有メモリセグメントを呼び出しプロセスのアドレス空間にアタッチします。 渡す必要がある引数は次のとおりです-

  • 最初の引数shmid *は、共有メモリセグメントの識別子です。 このidは共有メモリ識別子であり、shmget()システムコールの戻り値です。
*2番目の引数shmaddr* は、接続アドレスを指定するためのものです。 shmaddrがNULLの場合、システムはデフォルトで適切なアドレスを選択してセグメントを接続します。 shmaddrがNULLではなく、SHM_RNDがshmflgで指定されている場合、アタッチは、最も近いSHMLBAの倍数(下位境界アドレス)のアドレスに等しくなります。 それ以外の場合、shmaddrは、共有メモリのアタッチメントが発生/開始するページ境界アドレスでなければなりません。
*3番目の引数shmflg* は、SHM_RND(SHMLBAへの丸めアドレス)またはSHM_EXEC(セグメントのコンテンツの実行を許可)またはSHM_RDONLY(読み取り専用のセグメントの付加)などの必要な共有メモリフラグを指定します。デフォルトでは読み取り/書き込み)またはSHM_REMAP(shmaddrで指定された範囲内の既存のマッピングを置き換え、セグメントの終わりまで継続します)。

この呼び出しは、成功するとアタッチされた共有メモリセグメントのアドレスを返し、失敗すると-1を返します。 失敗の原因を知るには、errno変数またはperror()関数で確認してください。

#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr)

上記のシステムコールは、呼び出し元プロセスのアドレス空間から共有メモリセグメントを切り離すSystem V共有メモリセグメントの共有メモリ操作を実行します。 渡す必要がある引数は-

引数shmaddrは、切り離される共有メモリセグメントのアドレスです。 切り離されるセグメントは、shmat()システムコールによって返されたアドレスでなければなりません。

この呼び出しは、成功すると0を返し、失敗すると-1を返します。 失敗の原因を知るには、errno変数またはperror()関数で確認してください。

#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

上記のシステムコールは、System V共有メモリセグメントの制御操作を実行します。 次の引数を渡す必要があります-

最初の引数shmidは、共有メモリセグメントの識別子です。 このidは共有メモリ識別子であり、shmget()システムコールの戻り値です。

2番目の引数cmdは、共有メモリセグメントで必要な制御操作を実行するコマンドです。

cmdの有効な値は-

  • IPC_STAT -struct shmid_dsの各メンバーの現在の値の情報を、bufが指す渡された構造にコピーします。 このコマンドには、共有メモリセグメントへの読み取り権限が必要です。
  • IPC_SET -ユーザーID、所有者のグループID、権限などを設定します。 構造bufが指す。
  • IPC_RMID -破棄するセグメントをマークします。 セグメントは、最後のプロセスがセグメントを切り離した後にのみ破棄されます。
  • IPC_INFO -bufが指す構造体の共有メモリ制限とパラメータに関する情報を返します。
  • SHM_INFO -共有メモリによって消費されたシステムリソースに関する情報を含むshm_info構造体を返します。

3番目の引数bufは、struct shmid_dsという名前の共有メモリ構造体へのポインターです。 この構造の値は、cmdに従ってsetまたはgetに使用されます。

この呼び出しは、渡されたコマンドに応じて値を返します。 IPC_INFOとSHM_INFOまたはSHM_STATが成功すると、共有メモリセグメントのインデックスまたは識別子、または他の操作の場合は0、失敗の場合は-1が返されます。 失敗の原因を知るには、errno変数またはperror()関数で確認してください。

次のサンプルプログラムを考えてみましょう。

  • 2つのプロセスを作成します。1つは共有メモリへの書き込み用(shm_write.c)、もう1つは共有メモリからの読み取り用(shm_read.c)です。
  • プログラムは、書き込みプロセス(shm_write.c)による共有メモリへの書き込みと、読み取りプロセス(shm_read.c)による共有メモリからの読み取りを実行します。
  • 共有メモリ、書き込みプロセスで、サイズ1K(およびフラグ)の共有メモリを作成し、共有メモリをアタッチします
  • 書き込みプロセスは、共有メモリに1023バイトの「A」から「E」までのアルファベットを5回書き込みます。 最後のバイトはバッファの終わりを示します
  • 読み取りプロセスは共有メモリから読み取り、標準出力に書き込みます
  • プロセスアクションの読み取りと書き込みが同時に実行されます
  • 書き込みの完了後、書き込みプロセスが更新され、共有メモリへの書き込みの完了を示します(struct shmsegの完全な変数を使用)
  • 読み取りプロセスは共有メモリから読み取りを実行し、書き込みプロセスの完了の指示を受け取るまで出力に表示します(struct shmsegの完全な変数)
  • 単純化のために、また無限ループとプログラムの複雑化を避けるために、読み取りおよび書き込みプロセスを数回実行します

書き込みプロセスのコードは次のとおりです(共有メモリへの書き込み–ファイル:shm_write.c)

/*Filename: shm_write.c*/
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

#define BUF_SIZE 1024
#define SHM_KEY 0x1234

struct shmseg {
   int cnt;
   int complete;
   char buf[BUF_SIZE];
};
int fill_buffer(char *bufptr, int size);

int main(int argc, char* argv[]) {
   int shmid, numtimes;
   struct shmseg *shmp;
   char *bufptr;
   int spaceavailable;
   shmid = shmget(SHM_KEY, sizeof(struct shmseg), 0644|IPC_CREAT);
   if (shmid == -1) {
      perror("Shared memory");
      return 1;
   }

  //Attach to the segment to get a pointer to it.
   shmp = shmat(shmid, NULL, 0);
   if (shmp == (void *) -1) {
      perror("Shared memory attach");
      return 1;
   }

  /*Transfer blocks of data from buffer to shared memory*/
   bufptr = shmp->buf;
   spaceavailable = BUF_SIZE;
   for (numtimes = 0; numtimes < 5; numtimes++) {
      shmp->cnt = fill_buffer(bufptr, spaceavailable);
      shmp->complete = 0;
      printf("Writing Process: Shared Memory Write: Wrote %d bytes\n", shmp->cnt);
      bufptr = shmp->buf;
      spaceavailable = BUF_SIZE;
      sleep(3);
   }
   printf("Writing Process: Wrote %d times\n", numtimes);
   shmp->complete = 1;

   if (shmdt(shmp) == -1) {
      perror("shmdt");
      return 1;
   }

   if (shmctl(shmid, IPC_RMID, 0) == -1) {
      perror("shmctl");
      return 1;
   }
   printf("Writing Process: Complete\n");
   return 0;
}

int fill_buffer(char * bufptr, int size) {
   static char ch = 'A';
   int filled_count;

  //printf("size is %d\n", size);
   memset(bufptr, ch, size - 1);
   bufptr[size-1] = '\0';
   if (ch > 122)
   ch = 65;
   if ( (ch >= 65) && (ch <= 122) ) {
      if ( (ch >= 91) && (ch <= 96) ) {
         ch = 65;
      }
   }
   filled_count = strlen(bufptr);

  //printf("buffer count is: %d\n", filled_count);
  //printf("buffer filled is:%s\n", bufptr);
   ch++;
   return filled_count;
}

コンパイルおよび実行手順

Writing Process: Shared Memory Write: Wrote 1023 bytes
Writing Process: Shared Memory Write: Wrote 1023 bytes
Writing Process: Shared Memory Write: Wrote 1023 bytes
Writing Process: Shared Memory Write: Wrote 1023 bytes
Writing Process: Shared Memory Write: Wrote 1023 bytes
Writing Process: Wrote 5 times
Writing Process: Complete

読み取りプロセスのコードは次のとおりです(共有メモリから読み取り、標準出力に書き込む–ファイル:shm_read.c)

/*Filename: shm_read.c*/
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>

#define BUF_SIZE 1024
#define SHM_KEY 0x1234

struct shmseg {
   int cnt;
   int complete;
   char buf[BUF_SIZE];
};

int main(int argc, char *argv[]) {
   int shmid;
   struct shmseg *shmp;
   shmid = shmget(SHM_KEY, sizeof(struct shmseg), 0644|IPC_CREAT);
   if (shmid == -1) {
      perror("Shared memory");
      return 1;
   }

  //Attach to the segment to get a pointer to it.
   shmp = shmat(shmid, NULL, 0);
   if (shmp == (void *) -1) {
      perror("Shared memory attach");
      return 1;
   }

  /* Transfer blocks of data from shared memory to stdout*/
   while (shmp->complete != 1) {
      printf("segment contains : \n\"%s\"\n", shmp->buf);
      if (shmp->cnt == -1) {
         perror("read");
         return 1;
      }
      printf("Reading Process: Shared Memory: Read %d bytes\n", shmp->cnt);
      sleep(3);
   }
   printf("Reading Process: Reading Done, Detaching Shared Memory\n");
   if (shmdt(shmp) == -1) {
      perror("shmdt");
      return 1;
   }
   printf("Reading Process: Complete\n");
   return 0;
}

コンパイルおよび実行手順

segment contains :
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
Reading Process: Shared Memory: Read 1023 bytes
segment contains :
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
Reading Process: Shared Memory: Read 1023 bytes
segment contains :
"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
Reading Process: Shared Memory: Read 1023 bytes
segment contains :
"DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
Reading Process: Shared Memory: Read 1023 bytes
segment contains :
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
Reading Process: Shared Memory: Read 1023 bytes
Reading Process: Reading Done, Detaching Shared Memory
Reading Process: Complete