Communication between Linux Processes (Part 2): Using Message Queue, Share memory and Sockets

Tram Ho

Preamble

Hello everyone, to continue the series of articles learning about the process in Linux, today I would like to share with you the next part in learning the communication mechanisms between processes. in the Linux operating system. As we all know, Linux provides many communication mechanisms between different processes and in the previous article, I have learned about 2 mechanisms using Signal and Pipe (pipe). . In this article, we will learn together about the next two mechanisms, shared memory and message queue.

Shared memory

Concept

Shared memory is an interprocess communication (IPC) mechanism available in Linux and other Unix-like systems, when the same memory is used for two or more different processes.

In other process communication mechanisms such as pipes or message queues, steps need to be taken to send data from one process to another. However, for shared memory, there isn’t any data transfer that needs to be done here, all processes can access the shared memory. And communication is done through this shared memory, where changes made by one process can be viewed by another.

Here, processes share a physical memory through their address space mediation. A shared memory exists independently of processes, and when a process wants to access this memory, the process must attach that shared memory to each process’s own address space, and manipulate that memory. on it as a memory area itself.

Use shared memory

Linux provides the system functions used to create and use shared memory as follows: 1.shmget ()

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

In it, the arguments:

  • key : is the key that identifies a shared memory, it can be an arbitrary value or a value generated from the function ftok () – the function that creates a unique key.
  • size : is the size of the shared memory segment.
  • shmflg : specify a required flag (flag / s) for shared memory like IPC_CREAT (create new memory segment) or IPC_EXCL (Used with IPC_CREAT to create a new memory segment, and function call will not (if the segment already exists). Note that this argument also needs to be associated with access to shared memory, you need to set the appropriate permissions for your needs.

After the call will be successfully executed, shmget () returns an identifier for the shared memory segment.

2.shmat ()

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

In it, the arguments:

  • shmid : is the identifier of the shared memory segment and is the return value of the system call shmget ().
  • shmadrr : is to specify the address to mount a memory segment. Usually we will set it to NULL and when that happens, the system will choose the appropriate address to attach the segment by default.
  • shmflg : specifies a mandatory flag (flag / s) for shared memory such as SHM_RND (rounding the address to SHMLBA) or SHM_EXEC (allows the contents of the segment to be executed) or SHM_RDONLY (attach segment for read-only purposes, by default it is read-write) or SHM_REMAP (replaces existing mapping in the range specified by shmaddr and continues until segment ends).

After the successful call to this function, it returns the address to which the shared memory segment is mounted

3.shmdt ()

int shmdt(const void *shmaddr)

Once your progress is completed using shared memory then you will need to separate it from the shared memory. This is done by calling the system function shmdt (). shmaddr is the address of the split shared memory segment.

4.shmctl ()

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

The above system call helps to take control of a shared memory segment with:

  • shmid : is the identifier ID for the shared memory.
  • cmd : specifies a command to be used on shared memory including:
    • IPC_STAT – Copies information about the current values ​​of each element in the struct shmid_ds structure struct shmid_ds into the structure indicated by buf pointer. This command requires read permission for the shared memory segment.
    • IPC_SET – Set the User IDs, Owner’s group ID, permissions, etc. to be pointed to under the buf structure.
    • IPC_RMID – The segment marker will be canceled. The segment is only destroyed after the final process has split it.
    • IPC_INFO – Returns information about the shared memory limit and the parameters in the structure pointed by buf.
    • SHM_INFO – Returns the shm_info structure shm_info contains information about system resources consumed by the shared memory.
  • buf : is a pointer to a shared memory structure named struct shmid_ds . The values ​​of this structure will be used for either set or get in cmd .

All of the above system function calls, if an error occurs and fails, it returns -1. To

Evaluate the use of shared memory

  • The advantage of using shared memory is that there is no need to send data, which saves money and is the fastest method of exchanging between processes.
  • The downside of this approach is that it will cause certain difficulties in ensuring data integrity (coherence), for example how to know which data a process retrieves is the latest data. which other process has recorded? How to prevent two processes from writing data to the common memory at the same time? … Obviously shared memory needs to be protected by appropriate synchronization mechanisms .. Besides, shared memory is not It is a suitable choice in distributed systems, for exchanging information between different computers.

Message queue

Concept

Message queue or message queue is also an IPC mechanism available in Linux. Each transmitted data block is identified with a specific type (TYPE) and the receiver can receive that data depending on the type of data. In many use cases, this is more efficient than having to receive data in the FIFO way like pipes.

Using message queue

Similar to shared memory, in order to support process communication by message queue, the operating system also provides standard IPC (Interprocess communication) functions to perform process communication with message queue, basically functions. :

1.msgget () : returns the identifier ID for the newly created message queue or returns the identifier of an existing message queue along with its identifier key value.

int msgget(key_t key, int msgflg)

2. msgsnd () : This system function is used to put data into the message queue.

int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)

3. msgrcv () : This system function helps to get data out of a message queue.

int msgrcv(int msgid, const void *msgp, size_t msgsz, long msgtype, int msgflg)

4. msgctl () : This system function also helps in performing the manipulation of a message queue.

int msgctl(int msgid, int cmd, struct msqid_ds *buf)

Evaluate the use of message queue

Using message queue offers many different features compared to using shared memory or other IPC methods such as:

  • The unit that transmits information in this communication mechanism is a data block (or message) and has a defined type, so that processes can exchange data in a structured form.
  • When using shared memory, data is available for multiple access processes. However, when using the message queue, once a process has received data, it will no longer be used by any other process.
  • Unlike pipes, message queues are based on messages, while pipes are based on byte streams and the message queue does not necessarily have to be read first out first.
  • One downside of message queues is that the maximum length of each message is limited and the life cycle of the message queues attached to the kernel.

Conclusion

So, together we have learned about two more process communication mechanisms in linux, which are shared memory and message queue. And as I said in the previous article, each method has its own advantages and limitations for each use case. So, carefully assess your application’s needs and your application’s effectiveness when it comes to choosing a process communication mechanism.

Reference source

Share the news now

Source : Viblo