Tom*_*ale 9 logs x11 concurrency files
在模仿 MacOS 的终端open命令或 Window 的终端命令时start,此答案的注释建议将 stdout 和 stderr 附加到~/.xsession-errors,例如 ( bash):
alias open='&>>~/.xsession-errors xdg-open'
Run Code Online (Sandbox Code Playgroud)
我预见到的问题是竞争条件。lsof ~/.xsession-errors显示 22 个进程打开文件进行写入。
如何防止两个进程写入相同的偏移量~/.xsession-errors?
Gil*_*il' 14
当文件以追加模式打开时,操作系统保证所有写入都发生在最后。所以来自一个作者的数据不会覆盖来自另一个作者的数据。
这仅适用于文件以追加模式打开的情况,即>>在 shell 中打开。如果文件的创建者打开它,>则该保证将不适用,并且可能具有以下序列:
>out; 现在在位置 0>>out; 现在在位置 0hello,现在在位置 6world,这被写在位置 6 并且进程 2 现在在位置 12oops,这被写在位置 6 因为进程 1 的文件位置没有改变。在 Debian(自 2001 年左右)上,该文件.xsession-errors由`/etc/X11/Xsession 创建,并以追加模式打开,所以一切正常:
Run Code Online (Sandbox Code Playgroud)exec >>"$ERRFILE" 2>&1
我不知道所有登录到~/.xsession-errors.
只要每个人都以追加模式打开文件,就会出现所有输出。然而,输出可能是碎片化的。实际上,对常规文件的足够小的写入是原子的。任何小于 512B 的东西都应该在任何地方都足够小,我认为 Linux 能保证更多¹。因此,即使有多个并发写入者,每个日志行也应该完好无损,假设写入者使用行缓冲输出并且行不太长。
¹请注意,POSIX 不保证除管道外的任何内容。
>>在POSIX shell 中使用可保证文件将以O_APPEND.
如果
O_APPEND设置了文件状态标志的标志,则在每次写入之前应将文件偏移量设置为文件末尾,并且在更改文件偏移量和写入操作之间不应发生中间文件修改操作。
POSIX 定义了在一次调用中可以请求写入的最小字节数write(2)( SSIZE_MAX= 32,767 )。返回值是实际写入的字节数(保证原子性)。
并非所有文件系统都符合。从多个进程附加到文件说:
需要注意的是,并非所有文件系统都兼容 POSIX。两个著名的例子是 NFS 和 Hadoop 分布式文件系统 (HDFS)。在这些网络文件系统上,追加是模拟的并且受到竞争条件的影响。
虽然您可以使用 打开O_APPEND,但写入该文件的其他进程可能不会。您可以检查任何给定的文件:
lsof +fg <file>
Run Code Online (Sandbox Code Playgroud)
令人担忧的是,当我运行 时lsof +fg ~/.xsession-errors,我没有 AP看到(附加)标志,这表明我的列表中的 22 个进程(基于 Arch 的 Manjaro Linux)没有安全地打开文件。
仅当我cat >> ~/.xsession-errors在另一个 shell 中运行时,最终输出行才会包含该AP标志:
cat       3099 ravi    1w   REG   W,AP,LG   0,48      963 1926479 .xsession-errors
Run Code Online (Sandbox Code Playgroud)
如果有人知道应该在上游哪里提出这个问题,请发表评论。
如果所有进程都使用以下任一方式在本地打开文件:
open(2)和旗帜O_APPENDfopen(3)和"a"旗帜sh >>或bash &>>那么任何数据都不应该通过竞争条件被覆盖。
感谢@Gilles 的回答为我指明了正确的方向。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           12422 次  |  
        
|   最近记录:  |