AOS Experiment-2 and 3
AOS Experiment-2 and 3
Inter-Process Communication (IPC) allows processes to communicate and share data in the
kernel. There are multiple ways to implement IPC in the Linux kernel, including pipes, message
queues, shared memory, and semaphores. Below is a C program demonstrating IPC using
message queues and explaining kernel-level implications.
Code
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <unistd.h>
if (choice == 1) {
// Sender process
message.msg_type = 1;
printf("Enter message to send: ");
fgets(message.msg_text, sizeof(message.msg_text), stdin);
message.msg_text[strcspn(message.msg_text, "\n")] = '\0'; // Remove newline
} else if (choice == 2) {
// Receiver process
if (msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0) == -1) {
perror("msgrcv failed");
exit(EXIT_FAILURE);
}
printf("Received Message: %s\n", message.msg_text);
return 0;
}
Explanation
struct msg_buffer {
long msg_type;
char msg_text[100];
};
3. Sending a Message
msgctl() with IPC_RMID removes the message queue after receiving the message.
This prevents orphaned message queues in the system.
The kernel maintains message queues inside a system-wide message queue table.
Each queue has an ID, permissions, and message structure.
The msgget(), msgsnd(), and msgrcv() interact with the kernel IPC subsystem.
🔹 The kernel schedules IPC operations, ensures synchronization, and avoids race
conditions.
3. Message Queue Memory Management
If multiple processes try to read the same message, only one will receive it.
msg_type can be used as a priority mechanism to control message order.
Kernel uses semaphores & locks to prevent race conditions.
5. Security Implications
Step 1: Compile
./ipc
# Choose option 1 and enter a message
./ipc
# Choose option 2 to receive the message
Expected Output
Sender
Choose mode:
1. Send Message
2. Receive Message
1
Enter message to send: Hello from Process A
Message sent successfully!
Receiver
Choose mode:
1. Send Message
2. Receive Message
2
Received Message: Hello from Process A
Message queue deleted successfully.
1. Pipes
2. Shared Memory
3. Sockets
Conclusion
For this, we'll implement Shared Memory IPC using POSIX shared memory (shm_open)
and semaphores (sem_t). This method is efficient because it avoids excessive kernel
involvement and reduces context switching overhead, making it ideal for analyzing micro-
architectural behavior.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h> // For O_* constants
#include <sys/mman.h> // For shared memory
#include <sys/stat.h> // For mode constants
#include <semaphore.h> // For semaphores
#include <unistd.h> // For fork(), sleep()
#include <string.h> // For strcpy()
struct shared_data {
char message[BUFFER_SIZE];
};
int main() {
int shm_fd;
struct shared_data *shared_memory;
sem_t *semaphore;
if (pid == 0) {
// Child process (Reader)
printf("Reader: Waiting for data...\n");
sem_wait(semaphore); // Wait until writer process posts semaphore
} else {
// Parent process (Writer)
sleep(1); // Give reader time to start
return 0;
}
Micro-Architectural Implications
Traditional IPC (e.g., pipes, message queues) requires system calls (read(), write()),
leading to expensive context switches.
Shared memory IPC avoids system calls, reducing CPU mode switching
overhead.
Multiple cores use cache-line locking, leading to bus traffic and false sharing.
The Linux kernel ensures atomic writes using memory barriers.
Semaphores cause cache line invalidations, affecting L3 cache performance.
4. Performance Metrics
Step 1: Compile
./ipc_shared
Expected Output