Dav*_*vis 3 linux bash shell multiprocessing race-condition
shell脚本的修改版本将音频文件从FLAC转换为MP3格式.该计算机具有四核CPU.该脚本使用以下命令运行:
./flac2mp3.sh $(find flac -type f)
Run Code Online (Sandbox Code Playgroud)
这会将flac目录中的FLAC文件(文件名中没有空格)转换为mp3目录中的MP3文件(与文件名相同flac).如果目标MP3文件已存在,则脚本将跳过该文件.
问题是,有时两个脚本实例几乎同时检查是否存在相同的MP3文件,导致MP3文件损坏.
如何多次运行脚本(即每个核心一次),而不必在每个命令行上指定不同的文件集,而不覆盖工作?
更新 - 最小竞争条件
该脚本使用以下锁定机制:
# Convert FLAC to MP3 using tags from flac file.
#
if [ ! -e $FLAC.lock ]; then
touch $FLAC.lock
flac -dc "$FLAC" | lame${lame_opts} \
--tt "$TITLE" \
--tn "$TRACKNUMBER" \
--tg "$GENRE" \
--ty "$DATE" \
--ta "$ARTIST" \
--tl "$ALBUM" \
--add-id3v2 \
- "$MP3"
rm $FLAC.lock
fi;
Run Code Online (Sandbox Code Playgroud)
然而,这仍然留下了竞争条件.
"lockfile"命令提供了在没有竞争条件的情况下尝试为shell脚本执行的操作.该命令由procmail人员专门为此目的编写,并且可在大多数BSD/Linux系统上使用(因为procmail适用于大多数环境).
你的测试变成这样:
lockfile -r 3 $FLAC.lock
if test $? -eq 0 ; then
flac -dc "$FLAC" | lame${lame_opts} \
--tt "$TITLE" \
--tn "$TRACKNUMBER" \
--tg "$GENRE" \
--ty "$DATE" \
--ta "$ARTIST" \
--tl "$ALBUM" \
--add-id3v2 \
- "$MP3"
fi
rm -f $FLAC.lock
Run Code Online (Sandbox Code Playgroud)
或者,您可以使lockfile保持无限期重试,这样您就不需要测试返回代码,而是可以测试输出文件以确定是否运行flac.