Several IPC mechanisms are available for POSIX systems, including shared memory and message passing. Here, we explore the POSIX API for shared memory.
POSIX shared memory is organized using memory-mapped files, which associate the region of shared memory with a file. A process must first create a shared-memory object using the shm_open() system call, as follows:
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
Parameters:
name: The first parameter specifies the name of the shared-memory object.
Processes that wish to access this shared memory must refer to the
object by this name.
O_CREAT | O_RDWR : The subsequent parameters specify that the shared-memory
object is to be created if it does not yet exist (O_CREAT) and that the object is
open for reading and writing (O_RDWR).
The last parameter establishes the directory permissions of the
shared-memory object.
A successful call to shm_open() returns an integer file descriptor for the shared-memory object. Once the object is established, the ftruncate() function is used to configure the size of the object in bytes. The call
ftruncate(shm_fd, 4096);
sets the size of the object to 4, 096 bytes. Finally, the mmap() function establishes a memory-mapped file containing the shared-memory object. It also returns a pointer to the memory-mapped file that is used for accessing the shared-memory object.
Programs showing POSIX shared memory API for producer and consumer
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
int main()
{
const int SIZE = 4096;
const char * name = "OS" ;
const char * message_0 = "Hello" ;
const char * message_1 = "World!" ;
int shm_fd;
void * ptr;
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd, SIZE);
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
sprintf (ptr, "%s" , message_0);
ptr += strlen (message_0);
sprintf (ptr, "%s" , message_1);
ptr += strlen (message_1);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 4096;
const char * name = "OS" ;
int shm_fd;
void * ptr;
shm_fd = shm_open(name, O_RDONLY, 0666);
ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
printf ( "%s" , ( char *)ptr);
shm_unlink(name);
return 0;
}
|
The above programs can be compiled by typing the following commands in terminal opened in working directory –
gcc producer.c -pthread -lrt -o producer
gcc consumer.c -pthread -lrt -o consumer
./consumer & ./producer &
This should output the following –
HelloWorld!
The above programs use the producer–consumer model in implementing shared memory.
- The producer establishes a shared memory object and writes to shared memory, and the consumer reads from shared memory.
- The producer, creates a shared-memory object named OS and writes the famous string “Hello World!” to shared memory.
- The program memory-maps a shared-memory object of the specified size and allows writing to the object. (Obviously, only writing is necessary for the producer.)
- The flag MAP SHARED specifies that changes to the shared memory object will be visible to all processes sharing the object. Notice that we write to the shared-memory object by calling the sprintf() function and writing the formatted string to the pointer ptr.
- After each write, we must increment the pointer by the number of bytes written. The consumer process, reads and outputs the contents of the shared memory.
- The consumer also invokes the shm_unlink() function, which removes the shared-memory segment after the consumer has accessed it.
References
Silberschatz’s Operating System concepts
http://www.cse.cuhk.edu.hk/~ericlo/teaching/os/lab/7-IPC2/sync-pro.html
Last Updated :
31 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...