multithreadingshellexecmkfifo

why the command 'exec' can remove the blocking state of fifo file?


I'am studying how to use multi thread to process tasks.And i noticed that the fifo file can help that.here is the effect:

#!/bin/bash
my_cmd(){
echo "process $1"
sleep 3
}
ff="d:/myfifo/$$.fifo"
mkfifo $ff
exec 7<>$ff
for i in {1..10};do echo;done >&7
for i in {1..1000};do {
read -u 7
my_cmd $i
echo >&7
}& done
rm $ff
wait
echo "end"

This shell script can run normally(process 1000 cmds, 10 at a time).And i modified this script slightly

#!/bin/bash
my_cmd(){
echo "process $1"
sleep 3
}
ff="d:/myfifo/$$.fifo"
mkfifo $ff
exec 7<>$ff
for i in {1..10};do echo;done >$ff     # modified
for i in {1..1000};do {
read <$ff                              # modified
my_cmd $i
echo >$ff                              # modified
}& done
wait
rm $ff
echo "end"

As expected,the second script can also run normally.But i made a error when i modified it again.

#!/bin/bash
my_cmd(){
echo "process $1"
sleep 3
}
ff="d:/myfifo/$$.fifo"
mkfifo $ff
# exec 7<>$ff                                 modified
for i in {1..10};do echo;done >$ff    
for i in {1..1000};do {
read <$ff                              
my_cmd $i
echo >$ff                              
}& done
wait
rm $ff
echo "end"

The script wait a input to fifo file,because the fifo file entered a blocking state.It seems that this command 'exec 7<>$ff' lifted the blocking state of this fifo file.So is this the case?


Solution

  • On Linux, at least (Not sure about other OSes, and POSIX doesn't define a behavior), opening a fifo for both reading and writing will succeed at once without blocking waiting for the other end of the pipe to be opened.

    So when you commented out the exec 7<>$ff line, the next line for i in {1..10};do echo;done >$ff will opening the fifo for writing, and block waiting for something else to open it for writing before going on. With the original version using the exec, it was already opened for reading so there was no need to block.

    The Linux fifo(7) documentation does note

    A process that uses both ends of the connection in order to communicate with itself should be very careful to avoid deadlocks.