【问题标题】:What will happen two different background process access the same file in unix?两个不同的后台进程在unix中访问同一个文件会发生什么?
【发布时间】:2013-07-25 14:22:28
【问题描述】:

请在下面的cmd上给我解释一下:

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

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

由于作业在后台模式下运行,有人能解释一下可能的情况吗?

【问题讨论】:

  • 视情况而定。一般来说:坏事。
  • 会发生未定义的行为。
  • 与两个前台进程访问同一个文件的情况没有什么特别的不同。时间和缓冲都会在非确定性结果中发挥作用。
  • 好的,所以基本上写入和访问之间存在差异。在这里你只写 temp.txt 和 READ temp.txt 之后,所以不会发生任何不好的事情。您将在一个文件中的行数以及在第二个文件中输出的人。这就对了。这里的后台工作很快,他们做一些事情并完成,所以这里没有真正的并行性。如果它们一直在运行,那么我们可以考虑不同的场景。

标签: multithreading shell unix process


【解决方案1】:

这取决于。 cat(1) 可能会在其输入文件中看到一些东西或什么也没有。

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

  • who >f1
    一个孩子被分叉,输出文件被破坏,输出文件移动到孩子的标准输出,一个新的程序开始运行。
  • cat f2 | wc -l>f2
    一个孩子被分叉,一个管道被制造,另一个孩子被分叉,孩子们将他们的管道末端适当地移动到标准输入或标准输出,一个孩子运行一个命令,该命令将打开输入文件,另一个孩子 clobbers 输出,依此类推。

我不保证这实际上就是你的 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) 在第一个破坏者之前运行(看到旧数据?),也许不是。也许它在who(1) 有机会写输出之前运行,也许没有。

【讨论】:

    【解决方案2】:

    当cat 运行时temp.txt 的状态是你无法控制的(当cat 和who 相对于彼此运行时由调度程序决定),所以你无法预测会发生什么.更安全的版本是

    # 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-08
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      相关资源
      最近更新 更多