我编写了一个 C 程序,它分叉了 2 个进程,每个进程都使用
system()
调用 2 个脚本(script1.sh 和 script2.sh),我想要做的是让它们并行但在不同时刻写入文件(output.txt)。目前我的 script1.sh(来自进程 P1)首先写入文件,然后 script2.sh(来自进程 P2)写入同一个文件,但我需要它们以这种方式写入:
time 1: P1 writes 2 words in "output.txt"
time 2: P2 wirtes 3 words in "output.txt"
time 3: P1 writes 1 word in "output.txt"
time 4: P2 writes 6 words in "output.txt" etc...
我知道
system()
函数是同步的,但我成功地使用
system("script1.sh &")
问题是我不知道该怎么做,因为如果 P1 用“&”调用 script1.sh,它会在 P2 期间不间断地执行,所以这不是我想要的。我还知道如何使用以下方法停止 P1
pkill -f "script1.sh
所以也许它有帮助,但我不知道。
我该如何实现这个目标?谢谢
答案1
您可以做的是一个古老的 UNIX 技巧,即至少在标准 UNIX 文件系统中,文件重命名操作是原子的。
您可以执行以下操作:
有一个要写入的文件,例如输出。文件名将采用 3 种不同的形式:
- “输出”-实际文件
- “output.script1” - 脚本 1 要写入的文件名
- “output.script2”——用于写入 script2 的文件名。
每个脚本都会有一个机制来等待文件,然后选择并写入文件。例如,在脚本 1 中:
脚本1.sh:
function check_for_file {
local file=$1
if [[ -f "$1" ]];then
return 1
else
return 0
fi
}
function wait_for_file {
local file=$1
while (( `check_for_file $file` == 0 ))
do
# sleep 1 second and check again
sleep 1
done
}
# MAIN
# pass 1:
wait_for_file "output.script1"
# got file now
echo "whatever you need to write for pass 1" >> output.script
# done with first write, pass file to second script
mv "output.script1" "output.script2"
wait_for_file
# pass 2: do what I need to do for pass 2
# ... etc
然后可以将相同的脚本机制用于脚本 2。只需确保在脚本 2 中将其从脚本2 重命名即可。
然后有以下内容:
- 在您的 C 程序中,您可以先创建输出文件,然后先写入所需的任何内容(即 fopen("output", "w"))。如果需要,可以写入。关闭文件指针。
- 在后台启动脚本。(您拥有的系统调用)
- 将文件“output”重命名为“output.script1”,脚本1将会获取它。
答案2
也许您可以分叉 GNU Parallel 并将输出重定向到文件:
system("(echo script1.sh; echo script2.sh) | parallel > output.txt");