C Shared Memory 🎯

beginner
16 min

C Shared Memory 🎯

Welcome to this comprehensive guide on C Shared Memory! In this lesson, we'll explore how to share memory between multiple processes in C, a fundamental concept for building concurrent and efficient applications.

What is Shared Memory? 📝

Shared memory is a technique for allowing multiple processes to access the same block of memory. This is particularly useful when we want different processes to communicate with each other or share data without relying on inter-process communication (IPC) mechanisms such as pipes or sockets.

Why Use Shared Memory? 💡

Shared memory provides several advantages:

  • Improved Performance: Shared memory eliminates the overhead associated with IPC mechanisms, resulting in faster data transfer between processes.
  • Simplified Communication: Shared memory allows processes to communicate and share data more easily, making it a valuable tool for concurrent programming.
  • Efficient Resource Utilization: Shared memory enables multiple processes to share data structures, reducing memory usage and improving resource utilization.

Creating Shared Memory in C 💡

To create shared memory in C, we use the mmap() function from the unistd.h library. This function maps a file or anonymous memory into the calling process's address space.

Anonymous Shared Memory 📝

Anonymous shared memory is a shared memory region that does not have a backing file. Here's an example of creating an anonymous shared memory segment:

c
#include <stdio.h> #include <sys/mman.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #define SHARED_MEM_SIZE 4096 // Set the size of shared memory int main() { int shm_fd, shm_pid; void *shm_ptr; // Create shared memory with the given size shm_fd = shm_open( "/shm_anon", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR ); ftruncate( shm_fd, SHARED_MEM_SIZE ); // Map the shared memory to our process's address space shm_ptr = mmap( NULL, SHARED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 ); // Save the PID of the process that created the shared memory shm_pid = getpid(); printf("Process ID: %d\n", shm_pid); // Write some data to the shared memory sprintf( (char *)shm_ptr, "Hello, shared memory!" ); // Sync the shared memory with the backing file msync( shm_ptr, SHARED_MEM_SIZE, MS_SYNC ); // Unmap the shared memory from our process's address space munmap( shm_ptr, SHARED_MEM_SIZE ); // Close the shared memory file descriptor close( shm_fd ); return 0; }

In this example, we create an anonymous shared memory segment of size 4096 bytes and write the string "Hello, shared memory!" to it. The shared memory is mapped to our process's address space using the mmap() function.

Shared Memory with a Backing File 📝

Shared memory with a backing file is a shared memory region that has a file as its backing store. This allows us to preserve the shared memory across process termination and reuse it in subsequent runs. Here's an example of creating shared memory with a backing file:

c
#include <stdio.h> #include <sys/mman.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #define SHARED_MEM_FILE "shm_file" #define SHARED_MEM_SIZE 4096 // Set the size of shared memory int main() { int shm_fd, shm_pid; void *shm_ptr; // Open the shared memory file shm_fd = shm_open( SHARED_MEM_FILE, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR ); // Check if the shared memory file already exists if (shm_fd == -1) { perror("shm_open"); return 1; } // Ftruncate the shared memory file to the given size ftruncate( shm_fd, SHARED_MEM_SIZE ); // Map the shared memory to our process's address space shm_ptr = mmap( NULL, SHARED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 ); // Save the PID of the process that created the shared memory shm_pid = getpid(); printf("Process ID: %d\n", shm_pid); // Write some data to the shared memory sprintf( (char *)shm_ptr, "Hello, shared memory with backing file!" ); // Sync the shared memory with the backing file msync( shm_ptr, SHARED_MEM_SIZE, MS_SYNC ); // Unmap the shared memory from our process's address space munmap( shm_ptr, SHARED_MEM_SIZE ); // Close the shared memory file descriptor close( shm_fd ); return 0; }

In this example, we create a shared memory segment of size 4096 bytes with the file shm_file as its backing store. We write the string "Hello, shared memory with backing file!" to the shared memory and save it to the backing file using the mmap() and msync() functions.

Shared Memory Types 📝

In C, shared memory can be created with different types:

  1. PROT_NONE: No read or write access is allowed.
  2. PROT_READ: Only read access is allowed.
  3. PROT_WRITE: Only write access is allowed.
  4. PROT_READ | PROT_WRITE: Both read and write access is allowed.
  5. MAP_PRIVATE: The mapped file is copied into the process's address space, and changes made to the memory are not reflected in the original file.
  6. MAP_SHARED: The mapped file and the process's address space share the same memory, and changes made to either are reflected in both.

Cleaning Up Shared Memory 💡

It's essential to clean up shared memory when we're done using it to avoid memory leaks. We can unmap the shared memory and close its file descriptor to achieve this.

c
// Unmap the shared memory from our process's address space munmap( shm_ptr, SHARED_MEM_SIZE ); // Close the shared memory file descriptor close( shm_fd );

Quiz 🎯

Quick Quiz
Question 1 of 1

What function is used to create shared memory in C?

Quick Quiz
Question 1 of 1

What is the difference between PROT_READ and PROT_WRITE in C shared memory?