IPC Linux - sharmasadhna/mylearnings GitHub Wiki

PIPES

  1. Pipes(Unnamed pipes) (only b/w related process --> parent --> child) -->unidirectional, only 1 process can read/write, ex: find | grep --> runs on same terminal, running them on different terminals (unrelated process is not possible) --> system calls --> pipe(fd{2})--> create pipe with 2 File desc, fd1 for write, fd0 for read,
  2. Named Pipes(FIFO) (can be b/w unrelated process,ex: commands on 2 terminals ) --> bidirectional --> named pipes files created on system with mkfifo --> ex: mkfifo mypipe (on terminal), ls -la mypipe (1st char is p for pipe) --> in 1 terminal find ... > mypipe and in 2nd terminal grep .. < mypipe works now

Message Queue:

  1. for async communication (client need not wait for server to finish; ex: e-mailing system, pizza shop etc...)
  2. messages remain in message queue, in case the server crashes, or down for sometime, and these messages can be later picked by server when it;s up again. (message queue are maintained in kernel)
  3. If there are multiple messages (load of message is too high) multiple instances of server can process the data
  4. ex: of message q in distributed system: Kafka
  5. ordered/unordered Queue
  • a. ordered: FIFO, all messages must be processed in order, If any order failed to process then q is blocked, (ex: chat application)
  • b. unordered: If any message failed --> put that message to retry q and try with next message, later try again with that message after pushing it back of the q.

functions:

  1. msgget() --> create or initialize a queue
  2. msgsend()
  3. msgrecv()
  4. msgctl() --> some administrative control/delete q Every message in the q --> data + message type (a positive int value; helps server to segregate type of messages). Q's are differentiated based on their unique key (process use this key to function on different message Q's)

Shared Memory

Fastest, needs synchronization technique between 2 process, else memory corruption can happen a process writes to a "memory buffer" and other processes can come and read from that "memory buffer" Old POSIX functions:

  1. shmget() --> initialize the shared mem with a key and return shmid,
  2. shmat() --> attach the processes address space to the shared mem, with shmid
  3. server: initialize shmem if needed,do something and wait for clients
  4. shmdt() : detach address space from shared mem
  5. shmctl(): remove the shared memory New API mmap (memory mapped file --> more flexible) in place of shmget, also shm_open is the new API.

Sockets

Domain/Unix socket (AF_LOCAL/AF_UNIX) TCP/IP socket can also communicate between different machines --> so can be scaled in multi machine env TCP/IP (AF_INET) is comparables speed to AF_UNIX when used with localhost(127.0.0.1) no synchronization needed with 1 client/1 server server can handle multiple clients, with select() API

Dbus

libdbus system runs dbus daemon(uses libdbus)--> listens to all the clients on the bus --> clients can be informed of other process ex: system uses this for power management (??)

DBus is actually based on unix sockets. It only provides a standardized bus architecture to allow many processes to talk to each other without opening a ton of pipes or unix sockets. And it provides a standardized message serialization, which is nice.

A one to one ipc method has a large group of cooperating process can cause a dense mesh. But in case of a Dbus each process can connect to any number of process provided with a grant access. On a common single shared channel a user can connect with his own session or a new session without interfering the session of other user. This greatly increase the performance

Refer the link

https://blogs.gnome.org/abustany/2010/05/20/ipc-performance-the-return-of-the-report/

D Bus is superior to the traditional IPC mechanisms , mainly because of its ease of use, and the extra features it provides. Lemme list the most useful ones:

If the process which provides you a service you need is not currently running, the D-Bus daemon can wake the service up for you on demand; This way , the other service need not be always running in the background. It is only started when needed.
You could use broadcast messages to communicate with several processes at once. All the applications interested in your broadcasts will subscribe to your messages. This might be useful in a scenario where you want multiple applications to respond to an event.
D-Bus has various lanugage bindings- so you can use it easily from C/ C++/ Python etc.

For example, the shutdown command actually uses dbus to tell systems to set a new run level. Talking directly to dbus saves a step and may expose a richer interface than the command line.

Decision making step:

If an API is more convenient for you, because it allows you to write clear code or less code, then you should use it first. Once you have a working program, with a realistic data usage, then you can evaluate the performance of your program. By evaluating it, tracing it, you can get information on where the bottleneck is. If your bottleneck is IPC speed, then you can switch to a more complicated but faster API. Given a tradeoff between speed and readability, you should pick readability first, then measure. If IPC speed is still an issue, then you can make an informed choice. i.e if data is not that big, then choose sockets than shmem, as it involves too much sync and signaling