From b225bbbad926db4876e861031868c8cca751501a Mon Sep 17 00:00:00 2001 From: ae Date: Sun, 13 Oct 2024 19:34:28 +0300 Subject: [PATCH] docs: demo description --- README.md | 3 --- docs/PROJECT.md | 34 +++++++++++++++++++++++++++++++++ docs/media/system-overview.png | Bin 0 -> 25673 bytes 3 files changed, 34 insertions(+), 3 deletions(-) delete mode 100644 README.md create mode 100644 docs/PROJECT.md create mode 100644 docs/media/system-overview.png diff --git a/README.md b/README.md deleted file mode 100644 index 8fec84d..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# inter - -Simple inter-process communication demo \ No newline at end of file diff --git a/docs/PROJECT.md b/docs/PROJECT.md new file mode 100644 index 0000000..138126e --- /dev/null +++ b/docs/PROJECT.md @@ -0,0 +1,34 @@ +## Inter-process communication between two processes + +### System overview + +| Process | Description | +| ----------- | ------------------------------------------------------------------------------------------------- | +| `init` | Forks 4 child processes, reads data from them, and writes that data to the shared memory | +| `P1-P4` | Generates random priority number (in the range 0-19) and sends that priority number to the parent | +| `scheduler` | Creates the shared memory segment, reads data written into it, and prints that data | + +![Project system overview](./media/system-overview.png) + +### Implementation criteria + +**Criteria 1:** + +- Init is a parent process, which forks child processes P1-P4 (`fork` syscall) +- P1-P4: Process should generate a random integer number between 0-19 (random number generation or simply hardcoded) +- P1-P4 should send the random number to init through message passing (`pipe` syscall) +- Init should read data sent by P1-P4 + +**Criteria 2:** + +- Scheduler is an independent process: it should create a shared memory segmnet (`shmget` and related syscalls) +- Scheduler should read dadta (a list of random numbers) written by init, sort the list in ascending order, and print the list (sorting algorithm of choice) + +**Criteria 3:** + +- Init should attach to the shared memory created by the scheduler process (`shmat` and related syscalls, hardcoded to any unique key of choice -> `ftok` syscall is a clean way to accomplish this) +- Init should write random numbers from P1-P4 into the shared memory + +**Termination:** + +- After scheduler prints the data, init should detach from shared memory and scheduler should detach and delete the shared memory segment (`schmdt` and `shmctl` syscalls) diff --git a/docs/media/system-overview.png b/docs/media/system-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..f854d5c4315f996aac6b57b586f649ae99d8d67b GIT binary patch literal 25673 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