CentOSのFIFOと単純なbashの並列化

CentOSのFIFOと単純なbashの並列化

Ubuntu 20.04からCentOS Linux 8までの単純な並列実行を処理するためにbashスクリプトを調整するのに問題があります。スクリプトでは、FIFOから文字列を読み取って共通ファイルに出力する複数の「リーダー」を作成しました。文字列は、基本スクリプトからFIFOに直接渡されます。プロセスをきれいにするためにファイル記述子とロックを使用します。私はまだFIFOに書き込む前にすべての読者が起動するのを待っています。スクリプト全体を最後に配置しました。

スクリプトはUbuntuで完全に実行され、出力は次のようになります(最初の列はリーダーID、2番目の列はリーダーがFIFOから取得することです)。

2 1
4 2
1 3
...
3 4998
2 4999
4 5000

読み取りが完了すると、メッセージは1つずつ送信されます。

CentOSで同じスクリプトを使ってこれを得ました。

4 1
1 7
2 8
...
3 153
4 154
1 155

目立つジャンプがあり、メッセージ2〜6が完全に失われます。さらに、プロセスは155で早期に停止する。

何が起こったのか本当にわからない。どんなアイデアがありますか?

スクリプト:

#!/bin/bash

readers=4
objs=5000

echo "" > output.txt

# Temporary files and fifo
FIFO=$(mktemp -t fifo-XXXX)
START=$(mktemp -t start-XXXX)
START_LOCK=$(mktemp -t lock-XXXX)
FIFO_LOCK=$(mktemp -t lock-XXXX)
OUTPUT_LOCK=$(mktemp -t lock-XXXX)
rm $FIFO
mkfifo $FIFO

# Cleanup trap
cleanall() {
rm -f $FIFO
rm -f $START
rm -f $START_LOCK
rm -f $FIFO_LOCK
rm -f $OUTPUT_LOCK
}
trap cleanall exit

# Reader process
reader() {
    ID=$1    
    exec 3<$FIFO
    exec 4<$FIFO_LOCK
    exec 5<$START_LOCK
    exec 6<$OUTPUT_LOCK
    
    # Signal the reader has started
    flock 5                
    echo $ID >> $START
    flock -u 5
    exec 5<&- 

    # Reading loop
    while true; do
        flock 4  
        read -su 3 item
        read_status=$?
        flock -u 4  
        if [[ $read_status -eq 0 ]]; then
            flock 6
            echo "$ID $item" >> output.txt
            flock -u 6  
        else
            break # EOF reached
        fi
    done

    exec 3<&-
    exec 4<&-
    exec 6<&-
}

# Spawn readers
for ((i=1;i<=$readers;i++)); do
    reader $i &
done

exec 3>$FIFO

# Wait for all the readers
exec 5<$START_LOCK
while true; do
        flock 5
        started=$(wc -l $START | cut -d \  -f 1)
        flock -u 5
        if [[ $started -eq $readers ]]; then
            break
        else
            sleep 0.5s
        fi
done
exec 5<&-

# Writing loop
for ((i=1;i<=$objs;i++)); do
    echo $i 1>&3
done

exec 3<&- 
wait

echo "Script done"

exit 0

関連情報