0% found this document useful (0 votes)
16 views48 pages

LP Unit 4

This document covers signals and interprocess communication (IPC) in Linux, detailing the types of signals, their lifecycle, and handling mechanisms. It explains various IPC methods including pipes, FIFOs, message queues, semaphores, and shared memory, emphasizing their importance for data sharing, synchronization, and resource management. Additionally, it provides code examples for implementing signals and IPC mechanisms.

Uploaded by

hannanthesec
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views48 pages

LP Unit 4

This document covers signals and interprocess communication (IPC) in Linux, detailing the types of signals, their lifecycle, and handling mechanisms. It explains various IPC methods including pipes, FIFOs, message queues, semaphores, and shared memory, emphasizing their importance for data sharing, synchronization, and resource management. Additionally, it provides code examples for implementing signals and IPC mechanisms.

Uploaded by

hannanthesec
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

UNIT - 4

• Signals: Introduction, A list of signals, terminal


signals, Requesting an Alarm signal – alarm( ),
handling signals – signal( ), protecting critical code
and chaining interrupt handlers, sending signals –
kill( ), Death of children, suspending and Resuming
processes, process Group’s and control terminals.
• Interprocess communication: introduction to IPC,
pipes, FIFOs, introduction to three types of IPC –
message queues, semaphores and shared message
queues
Signals: Introduction
• In Linux, Signals are the interrupts that are sent to the
program to specify that an important event has
occurred.
• Events can vary from user requests to invalid memory
access errors.
• Various signals, like the interrupt signal, means that
the user has asked the program to perform something
which is not present in the user flow of control.
Signals: Introduction
• There are two kinds of signals:

• Maskable

• Non-Maskable

• Maskable: - Maskable Signals are the signals that the user can
change or ignore, for example, Ctrl +C.
Non-Maskable: - Non-Maskable Signals are the signals that
the users cannot change or ignore. Non-Maskable signals
mainly occur if a user is signaled for non-recoverable
hardware errors.
What is the Typical Lifecycle of a Signal?
• A signal goes through three stages:
• Generation
• Delivery
• Processing
A List of Common Signals
Signal Signal
Description Default Action
Number Name
Hangup detected on controlling
1 SIGHUP Terminate
terminal

2 SIGINT Interrupt from keyboard (Ctrl + C) Terminate

3 SIGQUIT Quit from keyboard (Ctrl + ) Terminate

Kill signal (cannot be caught or


9 SIGKILL Terminate
ignored)
15 SIGTERM Termination signal Terminate
Stop process (cannot be caught or
19 SIGSTOP Stop
ignored)

20 SIGTSTP Stop typed at terminal (Ctrl + Z) Stop

17 SIGCHLD Child process stopped or terminated Ignore

18 SIGCONT Continue if stopped Continue

14 SIGALRM Timer signal from alarm() Terminate


Terminal Signals
• Terminal signals are signals sent by the terminal (user
interaction) to processes, commonly via keyboard
shortcuts:

• SIGINT: Sent when pressing Ctrl + C (Interrupt


signal).

• SIGQUIT: Sent when pressing Ctrl + \ (Quit signal).

• SIGTSTP: Sent when pressing Ctrl + Z (Stop signal).


Requesting an Alarm Signal
• The alarm() system call is used to send a SIGALRM signal to
the process after a specified number of seconds. It’s useful for
timing out operations.

unsigned int alarm(unsigned int seconds);


seconds: Number of seconds after which the signal will be sent.
Returns: The number of seconds left for any previously scheduled alarm.
Requesting an Alarm Signal
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handle_alarm(int sig)
{
printf("Alarm signal received!\n");
}
int main() {
signal(SIGALRM, handle_alarm); // Set up signal handler for SIGALRM
alarm(5); // Set alarm for 5 seconds

printf("Waiting for alarm...\n");


Waiting for alarm...
pause(); // Wait for signal Alarm signal received!
return 0;
}
Handling Signals – signal()
• The signal() system call is used to catch and handle
signals by defining a custom signal handler function.

void (*signal(int signum, void (*handler)(int)))(int);

signum: The signal number to catch (e.g., SIGINT).


handler: A pointer to the signal-handling function.
Handling Signals – signal()
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handle_sigint(int sig) {
printf("Caught signal %d (SIGINT)\n", sig);
}
int main() {
signal(SIGINT, handle_sigint); // Set up signal handler for SIGINT
while (1) {
printf("Running... Press Ctrl+C to send SIGINT.\n");
sleep(2);
} Running... Press Ctrl+C to send SIGINT.
return 0;
} Caught signal 2 (SIGINT)
Protecting Critical Code and Chaining
Interrupt Handlers
• In multi-tasking systems, signals can be delivered to a process at
any time, potentially interrupting critical sections of the code.

• A critical section is a part of the code where shared resources


(like files or variables) are modified. If a signal handler interrupts
during such a section, it might lead to inconsistent or incorrect
behavior.

• To protect critical code, the delivery of certain signals is blocked


temporarily while the code is executing. This ensures that a
signal handler does not interrupt the critical section.
Protecting Critical Code and Chaining Interrupt
Handlers
#include <stdio.h> oldHandler = signal(SIGINT,
#include <signal.h> custom_sigint_handler);
#include <unistd.h> printf("I'm protected from Control-C
// New signal handler for SIGINT now (using custom handler)\n");
void custom_sigint_handler(int sig) sleep(3);
{ signal(SIGINT, oldHandler);
printf("Custom handler: Caught signal printf("I can be Control-C’ed again\n");
%d (SIGINT)\n", sig); sleep(3);
signal(SIGINT, SIG_DFL); printf("Bye!\n");
raise(sig); return 0;
} }
int main() { I can be Control-C’ed
I'm protected from Control-C now (using
void (*oldHandler)();
custom handler)
printf("I can be Control-C’ed\n"); Custom handler: Caught signal 2 (SIGINT)
sleep(3); I can be Control-C’ed again
Bye! ^C
Sending Signals – kill()
• The kill() system call is used to send a signal to a
#include <stdio.h>
specific process. #include <signal.h>
#include <unistd.h>
int kill(pid_t pid, int sig);
int main() {
pid: Process ID to send the signal to. pid_t pid = fork();
sig: The signal to send. if (pid == 0) {
printf("Child process
waiting...\n");
pause(); // Child waits for
Child process waiting... signal
Sending SIGINT to child process } else {
Child process received SIGINT (signal 2) printf("Sending SIGINT to
child process\n");
kill(pid, SIGINT); // Send
SIGINT to child
}
return 0;
}
Death of Children (SIGCHLD)
• When a child process terminates, the SIGCHLD signal is sent to
the parent process. The parent can handle this signal to avoid
creating zombie processes.
#include <stdio.h> if (pid == 0) {
#include <signal.h> printf("Child process running...\n");
#include <sys/wait.h> sleep(2);
#include <unistd.h> return 0;
} else {
void handle_sigchld(int sig) printf("Parent process waiting...\n");
{ pause(); // Wait for signal
wait(NULL); // Clean up the child }
process
printf("Child process terminated\n"); return 0;
} }

int main() {
signal(SIGCHLD, handle_sigchld); //
Parent process waiting...
Handle SIGCHLD
Child process running...
pid_t pid = fork();
Child process terminated
Suspend and Resume a Process
• In Linux, suspending and resuming processes can be done
using signals. Here’s how you can suspend and resume
processes programmatically or from the command line:
• 1. Suspending a Process:
• SIGSTOP: This signal is used to suspend a process. It cannot
be caught or ignored by the process. When a process receives
this signal, it stops executing until it is resumed.
• SIGTSTP: This signal is usually sent when the user presses
Ctrl+Z in the terminal to stop a process. Unlike SIGSTOP, the
process can catch and handle this signal.
• 2. Resuming a Process
• SIGCONT: This signal is used to resume a process that was
stopped with SIGSTOP or SIGTSTP.
Suspend and Resume a Process
#include <stdio.h> kill(pid, SIGSTOP); // Send SIGSTOP
#include <signal.h> signal to suspend child
#include <unistd.h>
#include <stdlib.h> sleep(3); // Wait for a bit
int main() printf("Resuming child process with
{ SIGCONT...\n");
pid_t pid = fork(); kill(pid, SIGCONT); // Send SIGCONT
if (pid == 0) { signal to resume child
// Child process sleep(3); // Wait and observe the resumed
printf("Child process running with PID: child
%d\n", getpid()); printf("Terminating child process...\n");
while (1) { kill(pid, SIGTERM); // Terminate the child
printf("Child is still running...\n"); process
Child process running with PID: 1234
sleep(2); }
Child is still running...
}
Child is still running...
} return 0;
Suspending child process with
else { }
SIGSTOP...
// Parent process
Resuming child process with
sleep(3); // Allow child to run for a bit
SIGCONT...
Child is still running...
printf("Suspending child process with
Child is still running...
SIGSTOP...\n");
Terminating child process...
Inter-Process Communication (IPC)
• Inter-Process Communication (IPC) is a crucial mechanism in operating systems that
allows different processes to communicate and synchronize their actions. IPC is essential
in multi-process or multi-threaded environments, enabling independent processes to work
together, share data, coordinate actions, and access shared resources.

• Why IPC is Important

• Data Sharing: IPC enables processes to share data, which is especially useful when
processes work collaboratively to perform tasks that require access to the same
information.

• Resource Sharing: IPC helps manage access to shared resources, such as files or memory,
preventing conflicts and data corruption.

• Synchronization: IPC provides methods for synchronizing processes, ensuring that tasks
happen in the correct order, especially in time-sensitive applications.

• Efficiency: IPC reduces redundancy by enabling processes to use a single source of data,
which can reduce memory usage and improve system performance.
Common IPC Mechanisms
• Pipes: Pipes are one of the simplest IPC mechanisms. They create a unidirectional
communication channel between processes (typically between a parent and child
process). Pipes are temporary and only exist during the life of the processes that use
them.

• Named Pipes (FIFOs): Named pipes, or FIFOs, are similar to pipes but have a name
in the filesystem, making them accessible by unrelated processes. FIFOs remain in the
system even after processes terminate, allowing different programs to communicate
through a persistent file-like structure.

• Message Queues: Message queues enable processes to send and receive messages in
a queue format, allowing asynchronous communication. Each message can have an
identifier, and processes can retrieve messages based on priority or ID. Message
queues are suitable for structured communication between processes without the need
for direct connections.
Common IPC Mechanisms
• Semaphores: Semaphores are synchronization primitives that help control access to
shared resources. They are often used to avoid race conditions by signaling when a
resource is available or being used. Semaphores can enforce mutual exclusion,
allowing only one process to access a critical section of code at a time.

• Shared Memory: Shared memory is one of the fastest IPC mechanisms, as it


provides a memory region that multiple processes can access directly. Shared memory
requires synchronization (usually with semaphores) to manage simultaneous access,
as multiple processes can read and write to this space.
Inter-Process Communication (IPC)
• Key Uses of IPC
• Coordination: IPC helps processes coordinate
complex tasks that require interaction and dependency.
• Parallel Processing: In applications where different
parts of a job are handled by separate processes, IPC
facilitates the sharing of intermediate data and results.
• Client-Server Communication: IPC enables client
applications to request services from server processes,
typical in networked and distributed systems.
Pipes
• Pipes are one of the most basic forms of Inter-
Process Communication (IPC), primarily used
to allow data to flow from one process to
another in a unidirectional manner.
• Pipes are commonly used to connect the output
of one process to the input of another, enabling
sequential data processing without intermediate
storage.
Types of Pipes
1.Anonymous Pipes:
•These are simple, unidirectional pipes used mainly for communication
between a parent and child process.
•Anonymous pipes are temporary and exist only while the processes are
running.They can only be used by processes that share a common
ancestor (usually a parent-child relationship).
•Created using the pipe() system call in C or by piping commands in
shell scripts (e.g., ls | grep txt).
2.Named Pipes (FIFOs):
•Unlike anonymous pipes, named pipes (or FIFOs) have a presence in
the file system and can be accessed by unrelated processes.
•Named pipes persist beyond the life of the processes that created them,
remaining available for other processes until explicitly deleted.
•Created using the mkfifo command or mkfifo() system call in C.
•Useful for long-running or unrelated processes that need to
communicate through a shared file.
Anonymous Pipes
Anonymous Pipes
#include <stdio.h> if (pid > 0) { // Parent process
#include <unistd.h> close(pipe_fd[0]); // Close reading end
#include <string.h> of the pipe
int main() write(pipe_fd[1], write_msg,
{ strlen(write_msg) + 1);
int pipe_fd[2]; close(pipe_fd[1]); // Close writing end
after sending data
pid_t pid;
} else { // Child process
char write_msg[] = "Hello from the parent
process!"; close(pipe_fd[1]); // Close writing end
of the pipe
char read_msg[100];
read(pipe_fd[0], read_msg,
// Create a pipe sizeof(read_msg));
if (pipe(pipe_fd) == -1) { printf("Child received: %s\n",
perror("Pipe failed"); read_msg);
return 1; close(pipe_fd[0]); // Close reading end
} after reading data
// Fork to create a child process }
pid = fork();
if (pid < 0) { return 0;
perror("Fork failed"); }
Named Pipes (FIFOs):
• Named Pipes, also known as FIFOs (First In, First Out), are a
type of pipe that allows unrelated processes to communicate by
passing data through a named entry in the filesystem.
• Unlike anonymous pipes, which are temporary and only exist as
long as the communicating processes do, named pipes persist in
the filesystem until they are explicitly removed, making them a
useful tool for coordinating long-running or separate programs.
Key Characteristics of FIFOs
• Named in the Filesystem: FIFOs appear as special files in the
filesystem. This means that any process with the correct
permissions can open and use a FIFO by referring to its name.
• Bidirectional, but Unidirectional Access at a Time: FIFOs
support bidirectional communication (both reading and writing),
but only in a sequential manner. A process must open the FIFO
in either read-only or write-only mode at any given time.
• Persistent Until Removed: Once created, a FIFO file remains
on the disk until it is manually deleted, allowing processes that
don’t start simultaneously to communicate through the FIFO at
any time.
• First In, First Out Behavior: FIFOs work on a queue basis,
ensuring that data written first will be read first.
// C program to implement one side of FIFO fd = open(myfifo, O_WRONLY);
// This side writes first, then reads // Take an input arr2ing from user.
#include <stdio.h> // 80 is maximum length
#include <string.h> fgets(arr2, 80, stdin);
#include <fcntl.h> // Write the input arr2ing on FIFO
#include <sys/stat.h> // and close it
#include <sys/types.h> write(fd, arr2, strlen(arr2)+1);
#include <unistd.h> close(fd);
int main()
{ // Open FIFO for Read only
int fd; fd = open(myfifo, O_RDONLY);

// FIFO file path // Read from FIFO


char * myfifo = "/tmp/myfifo"; read(fd, arr1, sizeof(arr1));
// Creating the named file(FIFO) // Print the read message
// mkfifo(<pathname>, <permission>) printf("User2: %s\n", arr1);
mkfifo(myfifo, 0666); close(fd);
}
char arr1[80], arr2[80]; return 0;
while (1) }
{
// Open FIFO for write only
Message Queues
• A message queue is an inter-process
communication (IPC) mechanism that allows
processes to exchange data in the form of
messages between two processes.
• It allows processes to communicate
asynchronously by sending messages to each
other where the messages are stored in a queue,
waiting to be processed, and are deleted after
being processed.
Message Queues
Functions of Message Queue
• 1. int msgget (key_t key, int msgflg);
• We use the msgget function to create and access a message
queue. It takes two parameters.
• The first parameter is a key that names a message queue in the
system.
• The second parameter is used to assign permission to the
message queue and is ORed with IPC_CREAT to create the
queue if it doesn't already exist. If the queue already exists,
then IPC_CREAT is ignored. On success, the msgget function
returns a positive number which is the queue identifier, while
on failure, it returns -1.
Functions of Message Queue
2. int msgsnd (int msqid, const void *msg_ptr, size_t msg_sz, int
msgflg);
• This function allows us to add a message to the message queue.
• The first parameter (msgid) is the message queue identifier
returned by the msgget function.
• The second parameter is the pointer to the message to be sent,
which must start with a long int type.
• The third parameter is the size of the message. It must not
include the long int message type.
• The fourth and final parameter controls what happens if the
message queue is full or the system limit on queued messages is
reached. The function on success returns 0 and place the copy of
message data on the message queue. On failure, it returns -1.
Functions of Message Queue
• 3. int msgrcv (int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int
msgflg);
• This function retrieves messages from a message queue.
• The first parameter (msgid) is the message queue identifier returned by the msgget
function.
• As explained above, the second parameter is the pointer to the message to be
received, which must start with a long int type.
• The third parameter is the size of the message.
• The fourth parameter allows implementing priority. If the value is 0, the first available
message in the queue is retrieved. But if the value is greater than 0, then the first
message with the same message type is retrieved. If the value is less than 0, then the
first message having the type value same as the absolute value of msgtype is
retrieved. In simple words, 0 value means to receive the messages in the order in
which they were sent, and non zero means receive the message with a specific
message type.
• The final parameter controls what happens if the message queue is full or the system
limit on queued messages is reached. The function on success returns 0 and place the
copy of message data on the message queue. On failure, it returns -1.
Functions of Message Queue
4. int msgctl (int msqid, int command, struct msqid_ds *buf);
The final function is msgctl, which is the control function.
• The first parameter is the identifier returned by the msgget
function.
• The second parameter can have one out of the below three
values.
Steps to Perform IPC using Message
Queues
Program For Usage of Message Queue
#include <sys/ipc.h> // Send message
#include <sys/msg.h> if (msgsnd(msgid, &msg, sizeof(msg.msg_text),
#include <stdio.h> 0) == -1) {
#include <stdlib.h> perror("msgsnd failed");
#include <string.h> }

struct message { // Receive message


long msg_type; if (msgrcv(msgid, &msg, sizeof(msg.msg_text),
char msg_text[100]; 1, 0) == -1) {
}; perror("msgrcv failed");
} else {
int main() { printf("Received message: %s\n",
msg.msg_text);
int msgid = msgget(IPC_PRIVATE, 0666 |
IPC_CREAT); }
if (msgid == -1) {
perror("msgget failed"); // Remove the message queue
exit(1); if (msgctl(msgid, IPC_RMID, NULL) == -1) {
} perror("msgctl failed");
}
struct message msg;
msg.msg_type = 1; return 0;
strcpy(msg.msg_text, "Hello from the sender!"); }
File Copy Using Message Queue
#include <stdio.h> exit(1);
#include <stdlib.h> }
#include <sys/ipc.h> // ---------------- Sender Section ----------------
#include <sys/msg.h> // Open the source file for reading
#include <string.h> FILE *source_file = fopen("source.txt",
"r");
#define MSG_KEY 12345 if (source_file == NULL) {
#define MSG_SIZE 1024 perror("fopen");
exit(1);
// Define message structure }
struct message {
long msg_type; // Read data from the file
char msg_text[MSG_SIZE]; struct message msg;
}; msg.msg_type = 1; // Message type
int main() { fread(msg.msg_text, 1, MSG_SIZE,
// Create a message queue source_file);
int msgid = msgget(MSG_KEY, fclose(source_file);
IPC_CREAT | 0666);
if (msgid < 0) {
perror("msgget");
// Write data to the destination file
// Send the message to the queue fwrite(received_msg.msg_text, 1,
if (msgsnd(msgid, &msg, strlen(msg.msg_text) + 1, 0) == -1) strlen(received_msg.msg_text), dest_file);
{ fclose(dest_file);
perror("msgsnd");
exit(1); printf("Receiver: Data written to 'destination.txt'.\n");
}
// Clean up the message queue
printf("Sender: Data sent to the message queue.\n"); msgctl(msgid, IPC_RMID, NULL);

// ---------------- Receiver Section ---------------- printf("Message queue removed.\n");


// Receive the message from the queue return 0;
struct message received_msg; }
if (msgrcv(msgid, &received_msg, MSG_SIZE, 1, 0) == -1) {
perror("msgrcv");
exit(1);
}

printf("Receiver: Data received from the message queue.\n");

// Open the destination file for writing


FILE *dest_file = fopen("destination.txt", "w");
if (dest_file == NULL) {
perror("fopen");
exit(1);
}
Introduction to Semaphores
• A semaphore is a synchronization mechanism
used to control access to a shared resource in
concurrent programming.
• It ensures that multiple threads or processes do
not simultaneously access critical sections,
potentially causing race conditions.
Types of Semaphores
• Binary Semaphore:
– Takes values 0 or 1.
– Acts as a simple lock (similar to a mutex).
• Counting Semaphore:
– Can take non-negative integer values.
– Useful for managing access to a pool of
resources.
Semaphore System Calls in C
• sem_init(): Initialize a semaphore.sem_wait():
Decrements (locks) the semaphore.
• sem_post(): Increments (unlocks) the
semaphore.
• sem_destroy(): Destroy the semaphore.
Semaphore System Calls in C
#include <stdio.h>
#include <stdlib.h> // Create threads
#include <pthread.h> for (int i = 0; i < NUM_THREADS; i++)
#include <semaphore.h> {
#include <unistd.h> int *thread_id = malloc(sizeof(int)); // Dynamically
#define NUM_THREADS 5 allocate memory for thread ID
sem_t semaphore; *thread_id = i + 1;
void *thread_function(void *arg) {
int thread_id = *(int *)arg; if (pthread_create(&threads[i], NULL, thread_function,
printf("Thread %d: Waiting to enter critical section...\n",thread_id) != 0) {
thread_id); perror("Failed to create thread");
sem_wait(&semaphore); // Lock the semaphore return 1;
printf("Thread %d: Entered critical section.\n", thread_id); }
}
// Simulate some work in the critical section
sleep(2); // Wait for all threads to finish
printf("Thread %d: Exiting critical section.\n", thread_id); for (int i = 0; i < NUM_THREADS; i++) {
sem_post(&semaphore); // Unlock the semaphore pthread_join(threads[i], NULL);
free(arg); // Free the dynamically allocated memory for }
thread ID
return NULL; // Destroy the semaphore
} sem_destroy(&semaphore);
int main() {
pthread_t threads[NUM_THREADS]; return 0;
// Initialize the semaphore with a value of 2 (allow up to 2}
threads in critical section)
sem_init(&semaphore, 0, 2);
Semaphore System Calls in C
gcc semaphore_example.c -o semaphore_example –lpthread
./semaphore_example

• Thread 1: Waiting to enter critical section...


• Thread 2: Waiting to enter critical section...
• Thread 3: Waiting to enter critical section...
• Thread 1: Entered critical section.
• Thread 2: Entered critical section.
• Thread 1: Exiting critical section.
• Thread 3: Entered critical section. Thread 2: Exiting critical section. Thread 3:
Exiting critical section.
• Thread 4: Waiting to enter critical section...
• Thread 5: Waiting to enter critical section...
• Thread 4: Entered critical section.
• Thread 5: Entered critical section.
• Thread 4: Exiting critical section.
• Thread 5: Exiting critical section.
What is Shared Memory?
• The Shared memory is a memory segment that
multiple processes can access concurrently.
• It is one of the fastest IPC methods because the
processes communicate by the reading and
writing to a shared block of the memory.
• Unlike other IPC mechanisms that involve the
more complex synchronization and data exchange
procedures shared memory provides the
straightforward way for the processes to share
data.
How Shared Memory IPC Works?
• The Shared memory IPC works by creating a memory segment that is
accessible by the multiple processes. Here’s a basic outline of how it operates:
• Creation of Shared Memory Segment: A process usually the parent, creates
a shared memory segment using the system calls like shmget() in Unix-like
systems. This segment is assigned the unique identifier (shmid).
• Attaching to the Shared Memory Segment: The Processes that need to
access the shared memory attach themselves to this segment using shmat()
system call. Once attached the processes can directly read from and write to
the shared memory.
• Synchronization: Since multiple processes can access the shared memory
simultaneously synchronization mechanisms like semaphores are often used
to the prevent race conditions and ensure data consistency.
• Detaching and Deleting the Segment: When a process no longer needs
access to the shared memory it can detach from the segment using shmdt()
system call. The shared memory segment can be removed entirely from
system using shmctl() once all processes have the detached.
How Shared Memory IPC Works?
System Calls for Shared Memory:
• shmget: Creates or accesses a shared memory segment.
• shmat: Attaches the shared memory segment to a process's
address space.
• shmdt: Detaches the shared memory segment.
• shmctl: Controls the shared memory (e.g., deleting, getting
status).
How Shared Memory IPC Works?
Shared Memory for Writer Process
#include <iostream> // shmat to attach to shared memory
#include <stdio.h> char* str = (char*)shmat(shmid,
#include <sys/ipc.h> (void*)0, 0);
#include <sys/shm.h>
using namespace std; cout << "Write Data : ";
cin.getline(str, 1024);
int main()
{ cout << "Data written in memory: "
// ftok to generate unique key << str << endl;
key_t key = ftok("shmfile", 65);
// detach from shared memory
// shmget returns an identifier in shmdt(str);
shmid
int shmid = shmget(key, 1024, 0666 | return 0;
IPC_CREAT); }
How Shared Memory IPC Works?
Shared Memory for Reader Process
#include <iostream> // detach from shared memory
#include <stdio.h> shmdt(str);
#include <sys/ipc.h>
#include <sys/shm.h> // destroy the shared memory
using namespace std; shmctl(shmid, IPC_RMID, NULL);

int main() return 0;


{ }
// ftok to generate unique key
key_t key = ftok("shmfile", 65);

// shmget returns an identifier in shmid


int shmid = shmget(key, 1024, 0666 |
IPC_CREAT);

// shmat to attach to shared memory


char* str = (char*)shmat(shmid, (void*)0, 0);

cout << "Data read from memory:" << str;


How Shared Memory IPC
Works?

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy