两个不同的后台进程会在unix中访问同一个文件会发生什么?

时间:2013-07-25 14:22:28

标签: multithreading shell unix process

请在下面的cmd解释我:

touch temp.txt
touch temp1.txt
who > temp.txt &
cat temp.txt | wc -l >temp1.txt  &

说一下temp.txt文件是一个空文件。 那么,执行后temp.txttemp1.txt文件中会出现什么。

有人可以解释可能的情况,因为作业是在后台模式下运行的吗?

2 个答案:

答案 0 :(得分:0)

运行temp.txtcat的状态超出您的控制范围(由catwho相对于彼此运行时由调度程序决定),所以你无法预测会发生什么。更安全的版本是

# These two commands are unnecessary. The files will be created
# when opened for writing.
# touch temp.txt
# touch temp1.txt
who | tee temp.txt | wc -l > temp1.txt &  # If it really needs to run in the background

答案 1 :(得分:0)

这取决于。 cat(1)可能会在其输入文件中看到某些内容或任何内容。

这是对最后两个命令中发生的事情的粗略描述。 (我忽略了touch(1)次调用,因为它们是同步的。)

  • who >f1
    分叉子项,输出文件被破坏,输出文件移动到子项的标准输出,并运行一个新程序。
  • cat f2 | wc -l>f2
    一个孩子分叉,另一个孩子分叉,孩子们根据需要将他们的管道末端移动到stdin或stdout,一个孩子运行一个命令,打开输入文件,另一个孩子blobbers输出,如上所述。 / LI>

我不保证这实际上就是你的shell正在做的事情 - 也许它在它的分叉之前就已经破坏了等等 - 但这已经足够接近了。所以,让我们把这些shell命令放在时间维上:

[time =====================================================================>]

# who >f1
-?->[clobber *f1*]-?->[dup to stdout]-?->[exec who(1)]-?->[...]

# cat f1 | wc -l>f2
-?->[pipe]-?->[fork]-?->[dup pipe]-?->[clobber *f2*]-?->[dup to stdout]-?->[exec wc(1)]
                +----?->[dup pipe]-?->[exec cat(1)]-?->[open *f1*]-?->[...]

上面的-?->箭头中的每一个都可能是任意长或短 - 你无法控制它。也许cat(1)之前运行第一个clobber(看到旧数据?),也许不是。也许它是在who(1)有机会写输出之前运行的,也许不是。