Общая память
Общая память - это память, совместно используемая двумя или более процессами. Однако зачем нам делиться памятью или какими-то другими средствами связи?
Повторюсь, каждый процесс имеет свое собственное адресное пространство, и если какой-либо процесс хочет передать некоторую информацию из своего адресного пространства другим процессам, то это возможно только с помощью методов IPC (межпроцессного взаимодействия). Как мы уже знаем, связь может быть между связанными или несвязанными процессами.
Обычно связь между связанными процессами осуществляется с помощью каналов или именованных каналов. Связь между несвязанными процессами (скажем, один процесс выполняется на одном терминале, а другой процесс на другом терминале) может осуществляться с помощью именованных каналов или популярных методов IPC, таких как общая память и очереди сообщений.
Мы видели методы IPC для каналов и именованных каналов, и теперь пришло время узнать остальные методы IPC, а именно общую память, очереди сообщений, семафоры, сигналы и отображение памяти.
В этой главе мы узнаем все об общей памяти.
Мы знаем, что для связи между двумя или более процессами мы используем общую память, но перед использованием общей памяти, что нужно сделать с системными вызовами, давайте посмотрим на это -
Создайте сегмент общей памяти или используйте уже созданный сегмент общей памяти (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 или функции perror ().
#include <sys/types.h>
#include <sys/shm.h>
void * shmat(int shmid, const void *shmaddr, int shmflg)
Вышеупомянутый системный вызов выполняет операцию совместно используемой памяти для сегмента совместно используемой памяти System V, т.е. присоединяет сегмент совместно используемой памяти к адресному пространству вызывающего процесса. Аргументы, которые необходимо передать, следующие:
The first argument, shmid,- идентификатор сегмента разделяемой памяти. Этот идентификатор является идентификатором разделяемой памяти, который является возвращаемым значением системного вызова shmget ().
The second argument, shmaddr,указать адрес прикрепления. Если shmaddr равен NULL, система по умолчанию выбирает подходящий адрес для присоединения сегмента. Если shmaddr не равен NULL и SHM_RND указан в shmflg, вложение равно адресу, кратному ближайшему к SHMLBA (адрес нижней границы). В противном случае shmaddr должен быть адресом, выровненным по странице, по которому происходит / начинается присоединение к общей памяти.
The third argument, 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, - это идентификатор сегмента разделяемой памяти. Этот идентификатор является идентификатором разделяемой памяти, который является возвращаемым значением системного вызова 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. Значения этой структуры будут использоваться либо для установки, либо для получения согласно cmd.
Этот вызов возвращает значение, зависящее от переданной команды. При успешном выполнении IPC_INFO и SHM_INFO или SHM_STAT возвращает индекс или идентификатор сегмента разделяемой памяти или 0 для других операций и -1 в случае неудачи. Чтобы узнать причину сбоя, проверьте с помощью переменной errno или функции perror ().
Давайте рассмотрим следующую примерную программу.
Создайте два процесса, один для записи в общую память (shm_write.c), а другой для чтения из общей памяти (shm_read.c)
Программа выполняет запись в общую память посредством процесса записи (shm_write.c) и чтение из общей памяти посредством процесса чтения (shm_read.c)
В общей памяти процесс записи создает общую память размером 1 КБ (и флаги) и присоединяет общую память.
В процессе записи в общую память записываются 5 раз алфавиты от «A» до «E» по 1023 байта каждый. Последний байт означает конец буфера
Процесс чтения будет читать из общей памяти и записывать на стандартный вывод
Действия процесса чтения и записи выполняются одновременно
После завершения записи процесс записи обновляется, указывая на завершение записи в общую память (с полной переменной в 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