Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inter-process communication without FIFOs

Inside a BASH script we can have multiple processes running in background which intercommunicate using named pipes, FIFOs registered on the filesystem. An example of this could be:

#!/bin/bash
mkfifo FIFO

# BG process 1
while :; do echo x; done & >FIFO

# BG process 2
while :; do read; done & <FIFO

exit

I wonder if it's possible to do the same intercommunication between background processes of a script without using a FIFO on filesystem, maybe with some kind of file-descriptor redirection.

like image 660
davide Avatar asked Jun 02 '12 14:06

davide


People also ask

What are different ways of inter-process communication?

Different ways of IPC are pipe, message passing, message queue, shared memory, direct communication, indirect communication and FIFO.

What are the two types of interprocess communication?

There are two primary models of interprocess communication: shared memory and. message passing.

Is inter-process communication necessary?

Why we need interprocess communication? There are numerous reasons to use inter-process communication for sharing the data. Here are some of the most important reasons that are given below: It helps to speedup modularity.


2 Answers

Here's an example that runs two subprocesses implemented as functions of the same shell-script... One subprocess generates numbers 1...5 (sleeps in between prints), the second one reads from a fixed filedescriptor (5, to which STDOUT of the first FD is redirected to), multiplies by 2 and prints again. The main process redirects STDOUT of that second process to another fixed filedescriptor (6) and later on reads from that one in the loop.

It works basically the same as you'd do in C-code with fd pairs created by the pipe(2) system call. To understand what's happening run the script under strace -f!

Bash Version is 4.2.24(1) running on Ubuntu/x86.

[ubuntu /home/chris]
$ bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Output of script:

[ubuntu /home/chris]
$ ./read_from_fd.sh
Got number 2.
Got number 4.
Got number 6.
Got number 8.
Got number 10.

Source code:

#!/bin/bash

# Generate data, output to STDOUT.
generate_five_numbers() {
        for n in `seq 5` ; do
                echo $n
                sleep 2
        done
}

# Read data from FD#5, multiply by two, output to STDOUT.
multiply_number_from_fd5_by_two() {
        while read n <&5 ; do
                echo "$(( $n * 2 ))"
        done
}

# choose your FD number wisely ;-)

# run generator with its output dup'ed to FD #5
exec 5< <( generate_five_numbers )

# run multiplyier (reading from fd 5) with output dup'ed to FD #6
exec 6< <( multiply_number_from_fd5_by_two )

# read numbers from fd 6
while read n <&6 ; do
        echo "Got number $n."
done

Process tree while running:

──read_from_fd.sh(8118)─┬─read_from_fd.sh(8119)───sleep(8123)
                        └─read_from_fd.sh(8120)
like image 175
Christian Vogel Avatar answered Sep 20 '22 11:09

Christian Vogel


Bash 4 has coprocesses.

You can also use anonymous named pipes, aka process substitution in Bash 2, 3 or 4.

like image 44
Dennis Williamson Avatar answered Sep 20 '22 11:09

Dennis Williamson