Originally Published: Friday, 24 August 2001 Author: Subhasish Ghosh
Published to: develop_articles/Development Articles Page: 5/5 - [Printable]

Understanding Linux Kernel Inter-process Communication: Pipes, FIFO & IPC (Part 2)

The Linux kernel is a thing of great beauty and learning to understand and appreciate its facets and edges is a worthy and noble pursuit. Take our hand as Linux.com offers this second part of Subhasish Ghosh's look at Inter-Process Communication in the Linux Kernel. Together we will find the grok, sooner or later.

  << Page 5 of 5  

IPC Shared Memory

Amongst all the three IPC Resources, the most useful IPC resource is the shared memory segment. Shared memory allows two or more processes to access some common data structures by placing them in a shared memory segment. Each process that wants to access the data structures included in a shared memory segment must add to its address space a new memory region, which maps the page frames associated with the shared memory segment. Each such frame can thus be easily handled by the Kernel through demand paging. The shmget() function is invoked to get the IPC Identifier of a shared memory segment, optionally creating it if it does not already exist. Then, shmat() function is invoked to "attach" a shared memory segment to a process, it then receives as its parameter the identifier of the IPC shared memory resource and tries to add a shared memory region to the address space of the calling process. The calling process can require a specific starting linear address for the memory region, but the address is usually unimportant, and each process accessing the shared memory segment can use a different address in its own address space. The function shmat() however, leaves the process's page tables unchanged. Another function, shmdt() is invoked to "detach" a shared memory segment specified by its IPC Identifier, that is, to remove the corresponding memory region from the process's adddress space. All readers should note the following very important points:

  1. Detaching a shared memory segment using shmdt() function DOES NOT delete the shared memory segment! It just makes it unavailable for the current process. When I started learning all this, I made this "mistakes" : I assumed using the shmdt() function deletes the shared memory segment. So, I want to warn all readers at this point. No, it does NOT ever "delete" the shared memory segment. Invoking shmdt() "detach"-es a shared memory segment. That's it.
  2. By itself, shared memory does NOT provide any sort of synchronization facilities. In other words, there are no automatic facilities to prevent a second process starting to read the shared memory before the first process has finished writing to it. It's the sole responsibility of the programmer to synchronize access to a shared memory segment.

An IPC shared memory segment descriptor, used primarily identifying shared memory segments, is a shmid_kernel data structure. So, let's see what this shmid_kernel data structure has in store for us. The shmid_kernel data structure may be represented as:

Type Field Description
struct ipc_perm u.shm_perm ipc_perm data structure
int u.shm_segsz Size of shared memory region (in bytes)
long u.shm_atime Last attach time
long u.shm_dtime Last detach time
long u.shm_ctime Last change time
unsigned short u.shm_cpid PID of creator
unsigned short u.shm_lpid PID of last accessing process
unsigned short u.shm_nattch Number of current attaches
unsigned long shm_npages Size of shared memory region (pages)
unsigned long * shm_pages Pointer to array of page frame PTEs
struct vm_area_struct * attaches Pointer to VMA descriptor list

Those fields which are accessible to User Mode processes are included within a shmid_ds data structure named u inside the descriptor. Their contents are accessed using the shmctl() function. The u.shm_segsz and shm_npages fields store the size of the shared memory segment in bytes and in pages, respectively. Although User Mode processes can require a shared memory segment of any length, the length of the allocated segment is a multiple of the page size, since the Kernel must map the shared memory segment with a memory region. The shm_pages field points to an array that contains one element for each page of the segment. The attached field points to the first element of a doubly linked list that includes the vm_area_struct descriptors of all memory regions associated with the shared memory segment. When mapping IPC shared memory segments, some fields of vm_area_struct descriptors have a special meaning. Let's now look at a code snippet illustrating shared memory segments in action.

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, int size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

IPC_STAT
IPC_SET
IPC_RMID

struct shmid_ds;

For creating a shared memory segment, we use the shmget system call. It takes a key, a size, and a flag paramater and returns an integer id for our segment. The flag can be combinations of IPC_CREAT and IPC_EXCL, as well as the permissions bits on the segment as described above. Once the segment is created and we have its id, we must attach it, or map it into memory. This is done with shmat. shmat works much the same as (in BSD) in that we can specify an address to map to, but the address must be a multiple of SHMLBA, unless we specify SHM_RND in the flags paramater. Various operations can be performed using shmctl. IPC_STAT can be used to fill in the struct shmid_ds structure. We can then set various fields (including changing ownership and premissions of ipc_perm) using IPC_SET. When all of our programs are done using a segment, we MUST shmctl it with IPC_RMID (the shmid_ds structure may be NULL), or else the segment will remain in memory forever. This is how a shared memory segments operates. Thus, this brings us to the end of this section, which in turn brings us to the end of this article too.

Thus, in this article we have seen what we mean by terms like IPC, IPC Resources, System V IPC, and different IPC mechanisms and resources; and more importantly how Unix Systems (more specifically GNU/Linux systems) implement them in reality. As the famous English poet, John Keats once mentioned: "A thing of beauty is joy forever". He was right. Linux, which forms the core of the GNU (GNU's Not Unix) operating system (which unfortunately everyone nowadays refers to as simply the "Linux OS"), is definitely a thing of beauty. And for enjoying this beauty, one needs to be passionate about 'Open Source Technologies' and especially towards Linux. Linux is far more advanced than it's many commercial competitors in so many ways. Just to name one, it is possible to fit both the Linux Kernel image and full root filesystem, including all fundamental system programs, on just one 1.44 MB floppy disk! No commercial Unix variants, to date, as far as I know, are able to boot from a single floppy boot diskette. In my next article, I will deal with Linux Memory Management, in other words, how and in what ways, does Linux implement Memory and other related features. So, get a Linux distribution today, learn some C coding; and if you are lucky and passionate, and like doing everything in life with all your heart and soul, becoming a Linux expert is just a matter of time... Take care all...

About the Author: My name is Subhasish Ghosh. I'm 20 years old, currently a computer-systems engineering student in India; a Microsoft Certified Professional (MCP), MCSD, MCP certified on NT 4.0, recently completed Red Hat Linux Certified Engineer (RHCE) Training & cleared Brainbench.com "Linux General Administration" certification exam. Have been installing, configuring and developing on Linux patform for a long time now, have had programmed using C, C++, VC++, VB, COM, DCOM, MFC, ATL 3.0, PERL, Python, POSIX Threads and Linux Kernel programming; currently holding a total of 8 International Industry Certifications. For a list of all my articles at Linux.com (and other sites), click here.
Latest News: My new friend from St. Petersburg, Russia, Annette (I call her Ann!), unfortunately refers to "Linux" as "Lunix"; my room resembles an O'Reilly & Wrox warehouse, my mom has warned me, either to clean my room by next week, or get out of the house along with my Compaq PC, Linux CDs and books! Looks like I need a new place real soon! E-mail: subhasish_ghosh@linuxmail.org





  << Page 5 of 5