并行运行代码的潜在危险

时间:2013-06-05 01:32:41

标签: c bash parallel-processing race-condition

我在OSX中工作,并为我的shell使用bash。我有一个脚本调用可执行文件数百次,每个调用独立于另一个。因此,我将并行运行此代码。但是,对可执行文件的每次调用都会将输出附加到新行上的社区文本文件中。

文本文件的顺序并不重要(尽管它很好,但完全不值得复杂,因为我只能使用unix sort命令),但是,是什么,可执行文件的每次调用都正确打印到文件。我担心的是,如果我并行地运行脚本,那么两个线程将检出文本文件,打印到它然后将不同的副本保存回文本文件的原始目录。从而使对文件的一个写入无效。

这实际发生了,还是我对打印文件的理解有缺陷?我不完全知道这是否也是个案基础,所以我将提供一些模拟代码,说明我的程序在下面做了什么。

脚本:

#!/bin/sh
abs=$1
input=$(echo "$abs" | awk '{print 0.004 + 0.005*$1 }')
./program input

“./程序”:

~~Normal .c file stuff here~~
~~VALUE magically calculated here~~
~~run number is pulled out of input and assigned to index for sorting~~

FILE *fpp;
fpp = fopen("Doc.txt","a");
fprintf(fpp,"%d, %.3f\n", index, VALUE);
fclose(fpp);

~Closing events of program.c~~

在bash中并行运行脚本的命令:

printf "%s\n" {0..199} | xargs -P 8 -n 1 ./program

感谢您提供任何帮助。

4 个答案:

答案 0 :(得分:3)

在open()中设置append标志的write()调用(如fwrite())(如fopen()期间)保证避免你描述的竞争条件。

O_APPEND 如果设置,则文件偏移量应在每次写入之前设置为文件的末尾。

来自:开放的POSIX规范:

opengroup.org open

答案 1 :(得分:2)

Race conditions正是您的想法。

不是100%肯定,但是如果你简单地附加到文件的末尾而不是打开它并且编辑它应该是正确的

答案 2 :(得分:2)

如果您有选项,请将程序写入标准输出而不是直接写入文件。然后你可以让shell合并程序的输出:

printf "%s\n" {0..199} | parallel -P 8 -n 1 ./program  > merged_output.txt

答案 3 :(得分:1)

是的,这看起来像是灾难的秘诀。如果这些进程在大致相同的时间点击打开文件,则只有一个进程“接受”。

我建议(更容易)写入单独的文件,然后在处理完成后将它们一起捕获,或者(更难)将所有结果发送到将为每个人写入文件的消费者进程。