Skip to content

Illustration of shared memory on linux for inter process communication

Notifications You must be signed in to change notification settings

grahamers/IPC-shared-memory-segment

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 

Repository files navigation

Shared Memory

Illustration of shared memory on linux for inter process communication

One of the most powerful IPC techniques is outlined here in a very basic example. There is sufficient code to demonstrate how strings (literals), integers, double and char types can be written to a shared memory segment on a server process. The same shared memory is read from a separate client process obviously running on same host.

The demo serves as a starting point, other forms of IPC will be added to various repositories.

This example uses cmake with;

OS: Ubuntu, Linux DESKTOP-2F28HHA 5.15.146.1-microsoft-standard-WSL2)\

Compiler: g++ version g++ 13.1.0. (with --std=c++23 set).

Overview:

Shared memory is exactly as its name suggests. A segment of memory can be created by a server say, and then attached to by any number of processes. Once processes have attached to the same shared memory segment, they can write to and read from that memory in a highly efficient manner.

There are caveats however. The manner in which memory is managed (written to/read from) is completely under the control of the developer. You get no shared data synchronistion for free, race conditions can happen, you manage your pointers; all memory management is up to you. Overwriting memory locations using incorrect pointer manipulation will cause debugging headaches. In summary, in its rawest form, shared memory gives you zero scope for error.

In subsequent examples, I will provide illustrations of how shared memory can be used in conjunction with bounded ring buffers, semaphores and other synchronistion constructs to provide a powerful IPC mechanism. .

The following diagram illustrates best;

image

This demo will write to and read from shared memory (the block in blue above). It will illustrate how pointer manipulation can dictate exactly where data is written to/read from. We'll see some interesting details regarding alignment. For debugging, 'gdb' with text interface (-tui) will illustrate both the memory locations (addresses) & contents.

The server will write to the segment and the client will read from it, specifically;

"PI is defined as: 22/7==3.14286

goodbye"

The above is expressed (written/read) as;

Breaking this down we have

image

There are 2 processes, server and client:

Server

Create the shared memory segment, attach to it and write data. At shutdown the memory is released back to the kernel.

In summary, the linux API's used are as follows;

key_t ftok(const char *pathname, int proj_id);

This creates an IPC key_t which can be compared to a FD for shared memory.

int shmget(key_t key, size_t size, int shmflg);

Using the key created via ftok, get an identifier for the shared memory we will be creating/using. Specify the size in bytes and flags such as IPC_CREATE (create segment if if doesnt exit), IPC_EXCL (fail if segment already exists).

Finally we attach to the newly created segment and get our hands on a void* pointer through which we can mmanipulate the segment as desired.

void *shmat(int shmid, const void *shmaddr, int shmflg);

Using the identifier obtained via shmget, attach to memory at an optional specify a start address (otherwise nullptr for kernel assigned) and set of flags 'shmflg' which apply some offset logic to shmaddr if it was specified.

image

We can examine details of the newly created segment using the 'ipcs' command. In the output below we can see a segment created by postgres as well as my server;

$ ipcs -m

------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00030471 0 postgres 600 56 6
0x0f20074e 7 gwalsh 666 1024 1\

At shutdown, the server will detach and release the shared memory using;

int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);\

Client

On the client side we will attach to segment created in server

image

Memory Access

The grid above illustrates the type and size of each of the datatypes that will be written server side and read from client side. Running the client and serverk we see;

When the server side shared memory is setup we have 1024 bytes available, initialised to 0 via the call to memset in the server.

Layout

At this point we have a shared memory segment setup between client and server, zero initialised. It can be visualised as;

image

REFERENCES:

https://www.ibm.com/docs/en/ztpf/2020?topic=apis-shmgetallocate-shared-memory

About

Illustration of shared memory on linux for inter process communication

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published