หน่วยความจำที่ใช้ร่วมกัน

หน่วยความจำร่วมคือหน่วยความจำที่ใช้ร่วมกันระหว่างสองกระบวนการขึ้นไป อย่างไรก็ตามเหตุใดเราจึงต้องแบ่งปันหน่วยความจำหรือวิธีการสื่อสารอื่น ๆ

เพื่อย้ำอีกครั้งว่าแต่ละกระบวนการมีพื้นที่แอดเดรสของตัวเองหากกระบวนการใดต้องการสื่อสารกับข้อมูลบางส่วนจากพื้นที่แอดเดรสของตัวเองไปยังกระบวนการอื่น ๆ จะเป็นไปได้ด้วยเทคนิค IPC (การสื่อสารระหว่างกระบวนการ) เท่านั้น ดังที่เราทราบกันดีอยู่แล้วว่าการสื่อสารอาจอยู่ระหว่างกระบวนการที่เกี่ยวข้องหรือไม่เกี่ยวข้องกัน

โดยปกติแล้วการสื่อสารระหว่างกระบวนการที่เกี่ยวข้องจะดำเนินการโดยใช้ Pipes หรือ Named Pipes กระบวนการที่ไม่เกี่ยวข้อง (เช่นกระบวนการหนึ่งที่ทำงานในเทอร์มินัลเดียวและอีกกระบวนการหนึ่งในเทอร์มินัลอื่น) การสื่อสารสามารถทำได้โดยใช้ Named Pipes หรือผ่านเทคนิค IPC ยอดนิยมของ Shared Memory และ Message Queues

เราได้เห็นเทคนิค IPC ของ Pipes และ Named ไปป์แล้วและตอนนี้ก็ถึงเวลาที่ต้องรู้เทคนิค IPC ที่เหลือ ได้แก่ Shared Memory, Message Queues, Semaphores, Signals และ Memory Mapping

ในบทนี้เราจะรู้ทุกอย่างเกี่ยวกับหน่วยความจำที่ใช้ร่วมกัน

เราทราบดีว่าในการสื่อสารระหว่างสองกระบวนการหรือมากกว่านั้นเราใช้หน่วยความจำที่ใช้ร่วมกัน แต่ก่อนที่จะใช้หน่วยความจำที่ใช้ร่วมกันสิ่งที่ต้องทำกับการเรียกระบบให้เราดูสิ่งนี้ -

  • สร้างเซ็กเมนต์หน่วยความจำแบบแบ่งใช้หรือใช้เซ็กเมนต์หน่วยความจำแบบแบ่งใช้ที่สร้างไว้แล้ว (shmget ())

  • แนบกระบวนการกับเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ที่สร้างไว้แล้ว (shmat ())

  • แยกกระบวนการออกจากเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ที่แนบมาแล้ว (shmdt ())

  • ควบคุมการดำเนินการบนเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ (shmctl ())

ให้เราดูรายละเอียดเล็กน้อยของการเรียกระบบที่เกี่ยวข้องกับหน่วยความจำที่ใช้ร่วมกัน

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

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

การเรียกระบบข้างต้นสร้างหรือจัดสรรเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ System V อาร์กิวเมนต์ที่ต้องส่งผ่านมีดังนี้ -

first argument, key,รู้จักเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ คีย์อาจเป็นได้ทั้งค่าตามอำเภอใจหรือค่าที่ได้มาจากฟังก์ชันไลบรารี ftok () คีย์นี้ยังสามารถเป็น IPC_PRIVATE ซึ่งหมายถึงการรันกระบวนการในฐานะเซิร์ฟเวอร์และไคลเอนต์ (ความสัมพันธ์แม่และลูก) เช่นการสื่อสารระหว่างกระบวนการที่เกี่ยวข้องกัน หากไคลเอ็นต์ต้องการใช้หน่วยความจำแบบแบ่งใช้กับคีย์นี้จะต้องเป็นกระบวนการย่อยของเซิร์ฟเวอร์ นอกจากนี้กระบวนการลูกจะต้องถูกสร้างขึ้นหลังจากที่ผู้ปกครองได้รับหน่วยความจำที่ใช้ร่วมกันแล้ว

second argument, size, คือขนาดของเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ที่ปัดเศษเป็นหลาย PAGE_SIZE

third argument, shmflg,ระบุแฟล็กหน่วยความจำแบบแบ่งใช้ที่ต้องการเช่น IPC_CREAT (การสร้างเซ็กเมนต์ใหม่) หรือ IPC_EXCL (ใช้กับ IPC_CREAT เพื่อสร้างเซ็กเมนต์ใหม่และการเรียกล้มเหลวหากมีเซ็กเมนต์นั้นอยู่แล้ว) จำเป็นต้องผ่านการอนุญาตเช่นกัน

Note - อ้างอิงส่วนก่อนหน้าสำหรับรายละเอียดเกี่ยวกับการอนุญาต

การเรียกนี้จะส่งคืนตัวระบุหน่วยความจำแบบแบ่งใช้ที่ถูกต้อง (ใช้สำหรับการเรียกหน่วยความจำที่แชร์เพิ่มเติม) เมื่อสำเร็จและ -1 ในกรณีที่เกิดความล้มเหลว หากต้องการทราบสาเหตุของความล้มเหลวให้ตรวจสอบด้วยฟังก์ชัน errno variable หรือ perror ()

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

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

การเรียกระบบข้างต้นดำเนินการดำเนินการหน่วยความจำแบบแบ่งใช้สำหรับเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ System V เช่นการแนบเซ็กเมนต์หน่วยความจำแบบแบ่งใช้กับพื้นที่แอดเดรสของกระบวนการเรียก อาร์กิวเมนต์ที่ต้องส่งผ่านมีดังนี้ -

The first argument, shmid,เป็นตัวระบุของเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ id นี้คือตัวระบุหน่วยความจำแบบแบ่งใช้ซึ่งเป็นค่าส่งคืนของการเรียกระบบ shmget ()

The second argument, shmaddr,คือการระบุที่อยู่ที่แนบ ถ้า shmaddr เป็น NULL ระบบจะเลือกแอดเดรสที่เหมาะสมเพื่อแนบเซ็กเมนต์ตามค่าเริ่มต้น หาก shmaddr ไม่ใช่ NULL และ SHM_RND ถูกระบุใน shmflg ไฟล์แนบจะเท่ากับแอดเดรสของ SHMLBA ที่ใกล้ที่สุด (Lower Boundary Address) มิฉะนั้น shmaddr ต้องเป็นที่อยู่ที่จัดแนวหน้าที่ซึ่งการแนบหน่วยความจำแบบแบ่งใช้เกิดขึ้น / เริ่มทำงาน

The third argument, shmflg, ระบุแฟล็กหน่วยความจำที่ใช้ร่วมกันที่ต้องการเช่น SHM_RND (ปัดเศษแอดเดรสออกเป็น SHMLBA) หรือ SHM_EXEC (อนุญาตให้เรียกใช้เนื้อหาของเซ็กเมนต์) หรือ SHM_RDONLY (แนบเซ็กเมนต์เพื่อจุดประสงค์แบบอ่านอย่างเดียวโดยค่าเริ่มต้นจะเป็นแบบอ่าน - เขียน) หรือ SHM_REMAP (แทนที่การแม็พที่มีอยู่ในช่วงที่ระบุโดย shmaddr และดำเนินการต่อไปจนถึงจุดสิ้นสุดของเซ็กเมนต์)

การเรียกนี้จะส่งคืนที่อยู่ของเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ที่แนบมาเมื่อสำเร็จและ -1 ในกรณีที่ล้มเหลว หากต้องการทราบสาเหตุของความล้มเหลวให้ตรวจสอบด้วยฟังก์ชัน errno variable หรือ perror ()

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

int shmdt(const void *shmaddr)

การเรียกระบบข้างต้นดำเนินการดำเนินการหน่วยความจำแบบแบ่งใช้สำหรับเซ็กเมนต์หน่วยความจำที่แบ่งใช้ของ System V ในการแยกเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ออกจากพื้นที่แอดเดรสของกระบวนการโทร ข้อโต้แย้งที่ต้องผ่านคือ -

อาร์กิวเมนต์ shmaddr คือที่อยู่ของเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ที่จะแยกออก ส่วนที่จะแยกออกต้องเป็นที่อยู่ที่ส่งคืนโดยการเรียกระบบ shmat ()

การโทรนี้จะส่งคืน 0 เมื่อสำเร็จและ -1 ในกรณีที่ล้มเหลว หากต้องการทราบสาเหตุของความล้มเหลวให้ตรวจสอบด้วยฟังก์ชัน errno variable หรือ perror ()

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

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

การเรียกระบบข้างต้นดำเนินการควบคุมการดำเนินการสำหรับเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ System V จำเป็นต้องส่งผ่านอาร์กิวเมนต์ต่อไปนี้ -

อาร์กิวเมนต์แรก shmid เป็นตัวระบุของเซ็กเมนต์หน่วยความจำแบบแบ่งใช้ id นี้คือตัวระบุหน่วยความจำแบบแบ่งใช้ซึ่งเป็นค่าส่งคืนของการเรียกระบบ shmget ()

อาร์กิวเมนต์ที่สอง cmd เป็นคำสั่งเพื่อดำเนินการควบคุมที่จำเป็นบนเซ็กเมนต์หน่วยความจำแบบแบ่งใช้

ค่าที่ถูกต้องสำหรับ cmd คือ -

  • IPC_STAT- คัดลอกข้อมูลของค่าปัจจุบันของแต่ละสมาชิกของ struct shmid_ds ไปยังโครงสร้างที่ส่งผ่านที่ชี้โดย buf คำสั่งนี้ต้องการสิทธิ์ในการอ่านสำหรับเซ็กเมนต์หน่วยความจำแบบแบ่งใช้

  • IPC_SET - ตั้งค่า ID ผู้ใช้ ID กลุ่มของเจ้าของสิทธิ์ ฯลฯ ที่ชี้ไปตามโครงสร้าง buf

  • IPC_RMID- ทำเครื่องหมายส่วนที่จะทำลาย เซ็กเมนต์จะถูกทำลายหลังจากกระบวนการสุดท้ายถอดออกแล้วเท่านั้น

  • IPC_INFO - ส่งคืนข้อมูลเกี่ยวกับขีด จำกัด หน่วยความจำแบบแบ่งใช้และพารามิเตอร์ในโครงสร้างที่ชี้โดย buf

  • SHM_INFO - ส่งคืนโครงสร้าง shm_info ที่มีข้อมูลเกี่ยวกับทรัพยากรระบบที่ใช้โดยหน่วยความจำแบบแบ่งใช้

อาร์กิวเมนต์ที่สาม buf เป็นตัวชี้ไปยังโครงสร้างหน่วยความจำแบบแบ่งใช้ที่ชื่อ struct shmid_ds ค่าของโครงสร้างนี้จะใช้สำหรับ set หรือ get ตาม cmd

การเรียกนี้คืนค่าขึ้นอยู่กับคำสั่งที่ส่ง เมื่อ IPC_INFO สำเร็จและ SHM_INFO หรือ SHM_STAT จะส่งกลับดัชนีหรือตัวระบุของเซ็กเมนต์หน่วยความจำแบบแบ่งใช้หรือ 0 สำหรับการดำเนินการอื่น ๆ และ -1 ในกรณีที่ล้มเหลว หากต้องการทราบสาเหตุของความล้มเหลวให้ตรวจสอบด้วยฟังก์ชัน errno variable หรือ perror ()

ให้เราพิจารณาโปรแกรมตัวอย่างต่อไปนี้

  • สร้างสองกระบวนการหนึ่งใช้สำหรับการเขียนลงในหน่วยความจำที่ใช้ร่วมกัน (shm_write.c) และอีกกระบวนการหนึ่งสำหรับการอ่านจากหน่วยความจำแบบแบ่งใช้ (shm_read.c)

  • โปรแกรมดำเนินการเขียนลงในหน่วยความจำแบบแบ่งใช้โดยกระบวนการเขียน (shm_write.c) และอ่านจากหน่วยความจำแบบแบ่งใช้โดยกระบวนการอ่าน (shm_read.c)

  • ในหน่วยความจำแบบแบ่งใช้ขั้นตอนการเขียนจะสร้างหน่วยความจำแบบแบ่งใช้ขนาด 1K (และแฟล็ก) และแนบหน่วยความจำแบบแบ่งใช้

  • กระบวนการเขียนจะเขียนตัวอักษร 5 เท่าจาก 'A' ถึง 'E' ของแต่ละ 1,023 ไบต์ลงในหน่วยความจำที่ใช้ร่วมกัน ไบต์สุดท้ายหมายถึงการสิ้นสุดของบัฟเฟอร์

  • กระบวนการอ่านจะอ่านจากหน่วยความจำที่ใช้ร่วมกันและเขียนไปยังเอาต์พุตมาตรฐาน

  • การอ่านและการเขียนกระบวนการดำเนินการพร้อมกัน

  • หลังจากเขียนเสร็จกระบวนการเขียนจะอัพเดตเพื่อระบุว่าการเขียนลงในหน่วยความจำแบบแบ่งใช้เสร็จสมบูรณ์ (พร้อมตัวแปรที่สมบูรณ์ใน 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