一个壳脚本从FLAC转换音频文件的修改版本MP3格式。计算机有一个四核CPU。该脚本是用运行:

./flac2mp3.sh $(find flac -type f)

此转换在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;

然而,这仍然留下了竞争条件。

有帮助吗?

解决方案

在“锁文件”命令提供你想要的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

另外,你可以把锁文件不断重试下去,所以你不需要测试返回码,而是可以测试输出文件以确定是否运行FLAC。

其他提示

如果您还没有lockfile,不能安装它(在任何版本的 - 有几个实现)一个强大的和便携式原子互斥mkdir

如果您尝试创建已存在于目录中,mkdir会失败,所以你可以检查是什么;当创建成功,你必须保证没有其他的合作过程是在同一时间,你的代码的关键部分。

if mkdir "$FLAC.lockdir"; then
    # you now have the exclusive lock
    : critical section
    : code goes here
    rmdir "$FLAC.lockdir"
else
    : nothing? to skip this file
    # or maybe sleep 1 and loop back and try again
fi

有关完整性,也许还找flock如果你是一组平台,在那里被可靠地提供,需要一个高性能的替代lockfile

您可以实现的,它的工作FLAC文件锁定。是这样的:

if (not flac locked)
  lock flac
  do work
else
  continue to next flac

发送输出到一个临时文件具有一个唯一的名称,然后重命名文件为所需的名称。

flac -dc "$FLAC" | lame${lame_opts} \
      --tt "$TITLE" \
      --tn "$TRACKNUMBER" \
      --tg "$GENRE" \
      --ty "$DATE" \
      --ta "$ARTIST" \
      --tl "$ALBUM" \
      --add-id3v2 \
      - "$MP3.$$"
mv "$MP3.$$" "$MP3"

如果通过文件的竞争条件泄漏在一段时间锁定系统每一次,最终输出将仍然是一个进程的结果。

要锁定文件过程可以创建一个文件与具有.lock扩展相同的名称。

开始编码检查.lock文件的存在,并且任选地确保锁文件的日期不是太旧(在情况下的处理管芯)之前。如果它不存在,则创建的编码开始之前,将其取出的编码完成后。

您也可以蜂拥而至的文件,但这个只有真正的作品在C你在哪里调用flock()和写入文件,然后关闭和解锁。对于一个shell脚本,你可能被调用另一个实用程序执行文件的写入。

如何写一个Makefile?

ALL_FLAC=$(wildcard *.flac)
ALL_MP3=$(patsubst %.flac, %.mp3, $(ALL_FLAC)
all: $(ALL_MP3)
%.mp3: %.flac
        $(FLAC) ...

然后做

$ make -j4 all

在bash中有可能设置noclobber选项,以避免文件重写。

帮助集| egrep的 '了noclobber | -C'

使用如富勒姆(无锁管理器)的工具和简单的序列化你的命令如下:

flom -- flac ....
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top