两个脚本写入同一个文件时未出现竞争条件

Anu*_*Rai 3 shell scripting bash parallelism

我有两个并行运行的脚本,它们回显到同一个文件。一个脚本正在回显+++++++++++++++该文件,而另一个脚本正在回显===========该文件。

下面是第一个脚本

#!/bin/bash
while [ 1==1 ];
do
    echo "+++++++++++++++" >> log.txt
    # commands
done
Run Code Online (Sandbox Code Playgroud)

下面是第二个脚本

#!/bin/bash
while [ 1==1 ];
do
    echo "===========" >> log.txt
    # commands
done
Run Code Online (Sandbox Code Playgroud)

log.txt 文件打印了大约 1400000 行,并且没有一行有像 ++== 之类的混乱大小写?

Linux 是否可以防止这种混乱的发生?如果可以,那么如何以及为什么?

Fré*_*yer 7

简单地说,该echo命令触发一个write原子系统调用。

\n

请注意,write\xe2\x80\x99 并不能保证写入给定的所有字节,但在这种情况下(很少数据),它可以。

\n

那么理论上write(fd, buffer, n)可以写入少于n字节并返回实际写入的写入字节数,以使程序能够写入字节buffer+n

\n

管道可能会发生这种情况,因为管道没有\xe2\x80\x99t 具有无限容量。

\n

write(2)

\n
\n

如果文件是使用 O_APPEND 打开(2)的,则在写入之前首先将文件偏移量设置为文件末尾。文件偏移量的调整和写入操作作为原子步骤执行。

\n
\n
\n

根据 POSIX.1,如果 count 大于 SSIZE_MAX,则结果是实现定义的;有关 Linux 上的上限,请参阅注释。

\n
\n

  • “write”系统调用没有理由写入部分缓冲区,那么所有行都不会混乱。但是如果你尝试`strace cat /boot/vmlinuz* >/dev/null`,你会发现文件是按块读写的:整个副本不是原子的。对于单个程序的文本输出,“fprintf”可以缓冲文本,并且在执行“fflush”时只需很少的“write”系统调用即可发送整个内容。 (5认同)
  • 这还不是完整的故事:这里使用“>>”是相关的,因为这会导致使用“O_APPEND”打开文件,这意味着每个“write”总是(原子地)写入到文件的末尾文件。在另一种情况下,进程执行“打开文件,将文件指针移至末尾,写入”(没有“O_APPEND”),您可以获得混合效果(如果一个进程设法在设置文件的另一个进程之间执行“写入”指针和书写)。 (2认同)