CentOS 上的 FIFO 和简单的 bash 并行化

CentOS 上的 FIFO 和简单的 bash 并行化

我在调整 bash 脚本来处理从 Ubuntu 20.04 到 CentOS Linux 8 的简单并行执行时遇到问题。在脚本中,我生成了多个“读取器”,它们从 FIFO 读取字符串并将其输出到公共文件中。字符串直接从主脚本传递到 FIFO。我使用文件描述符和锁来使进程变得干净。我还在等待所有读取器在写入 FIFO 之前启动。我将整个脚本放在最后。

该脚本在 Ubuntu 上完美运行,输出如下(第一列是读卡器 ID,第二列是读卡器从 FIFO 获取的内容)

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

读取完毕,消息一一传送。

在 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

相关内容