同时从子进程和父进程写入文件

Writing to a file from a subprocess and parent process simultaneously

我有一个脚本 (Python) 使用子进程调用另一个脚本。父脚本同时写入控制台和日志文件(我使用 this question 接受的答案中的代码来拆分输出),但子进程打印语句只会输出到标准输出,而不是日志文件。

我知道这是为什么:子进程将 stdout 设置为普通 stdout,而不是父进程具有的特殊 tee 对象。我尝试将 tee 对象作为参数传递给子进程,但我了解到不能将对象作为参数传递给子进程的艰难方法。我的备份计划是传入要写入的文件的路径字符串,然后让子进程使用相同的文件创建自己的 tee 对象。

我的问题是,如果两个进程同时写入同一个文件,输出会不会乱了?我在父进程中使用 open("file", 'w') ,它首先被调用,我在子进程。假设文件应该包含正确顺序的 print 语句的输出,因为使用 'a' 附加到文件意味着这些行将始终添加到当前文件末尾的位置,不是吗?或者是否有关于打开文件的规则阻止它同时被 2 个进程打开?

POST_TEST: 自己做了一些测试后,发现如下: -允许您连续多次打开("file", 'w') -允许您打开("file", 'w') 然后打开("file", 'a') - 第一种情况,子进程完全覆盖文件。 - 第二种情况,顺序不对,好像有部分输出丢失了。

那么我的新问题是,我应该使用什么替代解决方案来同时从父进程和子进程写入文件,而不会使行乱序或重叠?

感谢 Bamar 的建议:对第一个和第二个 open() 都使用 'a' 有效。如果您需要对一个已经存在的文件执行此操作,您可以使用 file.truncate() 在附加到文件之前清空该文件。

'w' 模式打开文件会截断文件 (as documented). Opening a file in 'a' mode may work on some systems. POSIX says for O_APPEND flag:

If set, the file offset shall be set to the end of the file prior to each write.

write()s that are larger than PIPE_BUF may interleave:

POSIX.1-2008 does not say whether write requests for more than {PIPE_BUF} bytes are atomic, but requires that writes of {PIPE_BUF} or fewer bytes shall be atomic.


Q: what alternative solution should I use to write to a file from both the parent and child process at the same time, without getting lines out of order or overlapping?

使用行缓冲模式 (1) 打开文件,刷新每行末尾的内部缓冲区——它应该保留行的大致相对顺序。如果行数小于 PIPE_BUF(在我的系统上是 4096 字节)那么它们不应该是 "overlap".


子进程可以将数据写入其标准输出,而您的父 Python 进程可以按照您喜欢的任何顺序将数据写入文件。参见 how teed_call() function is implemented