Questions about FIFO and file descriptor

I write a script as follows:

N=5
FIFO=/tmp/$$.fifo
mkfifo $FIFO

loop(){
    for i in $(seq 1 $N); do
        read tmp < $FIFO
        echo "$i out"
    done
}

loop &
LOOP_PID=$!
for i in $(seq 1 $N); do
    echo $i > $FIFO
    echo "$i in"
done
wait $LOOP_PID

When I run the script, it stops at wait $LOOP_PIDand cannot continue.

Therefore, I modify the script with a file descriptor:

N=5
FIFO=/tmp/$$.fifo
mkfifo $FIFO
exec 3<>$FIFO

loop(){
    for i in $(seq 1 $N); do
        read -u3 tmp
        echo "$i out"
    done
}

loop &
LOOP_PID=$!
for i in $(seq 1 $N); do
    echo $i >&3
    echo "$i in"
done
wait $LOOP_PID

That was normal.

When I use FIFO directly, it cannot read data from FIFO continuously, and it will freeze. When I use the file descriptor, everything is fine. what is the reason?

+4
source share
1 answer

Replace this:

loop(){
    for i in $(seq 1 $N); do
        read tmp < $FIFO
        echo "$i out"
    done
}

Wherein:

loop(){
    for i in $(seq 1 $N); do
        read tmp
        echo "$i out"
    done < $FIFO
}

This keeps the fifo open, not re-opening and re-closing it with each cycle.

FIFOs are quite complex:

  • An attempt to write to FIFO will be blocked if another process is not ready to read from FIFO.

  • FIFO FIFO, .

, . read tmp < $FIFO , FIFO? read , FIFO , .

exec

. FIFO :

#!/bin/sh
fifo=/tmp/$$.myfifo
mkfifo "$fifo"
echo $'1\n2\n3\n4'>"$fifo"

for i in {1..4}
do
    read  tmp
    echo $tmp
done <"$fifo"

script echo, , FIFO. , read tmp , script .

exec :

#!/bin/sh
fifo=/tmp/$$.myfifo
mkfifo "$fifo"
exec 3<>"$fifo"
echo $'1\n2\n3\n4'>&3

for i in {1..4}
do
    read -u3 tmp
    echo $tmp
done

script . , . , echo FIFO, FIFO. , , read -u3 tmp.

+3

All Articles