我有一个脚本(Python),它使用子进程来调用另一个脚本。父脚本同时写入控制台和日志文件(我使用了this question接受的答案中的代码来分割输出),但子进程打印语句只是stdout,而不是日志文件。
我知道这是为什么:子进程将stdout设置为普通stdout,而不是父进程具有的特殊tee对象。我尝试将tee对象作为参数传递给子进程,但我学到了很难将对象作为参数传递给子进程的方法。我的备份计划是传入要写入的文件的路径字符串,然后让子进程使用相同的文件创建自己的tee对象。
我的问题是,如果两个进程同时写入同一个文件,输出会搞砸吗?我在父进程中使用open(" file",' w'),首先调用它,然后我使用open("子进程中的文件",' a')。假设,文件应该以正确的顺序包含print语句的输出,因为附加到文件中的' a'意味着行总是被添加到当前文件的末尾,不是吗?或者是否有关于打开文件的规则,以防止它被2个进程同时打开?
POST_TEST:自己做了一些测试后,我发现了以下内容: - 你可以连续多次打开("文件",' w') - 你可以打开("文件",' w')然后打开("文件",' a') - 在第一种情况下,子进程完全覆盖该文件。 - 在第二种情况下,顺序不正确,某些输出似乎丢失了。
我的新问题是,我应该使用什么替代解决方案同时从父进程和子进程写入文件,而不会出现乱序或重叠的行?
答案 0 :(得分:0)
感谢Bamar提出建议:对第一个和第二个open()工作使用'a'。如果需要对已存在的文件执行此操作,可以使用file.truncate()清空文件,然后再附加到该文件。
答案 1 :(得分:0)
以'w'
模式打开文件会截断文件(as documented)。以'a'
模式打开文件可能适用于某些系统。 POSIX says for O_APPEND
flag:
如果设置,则文件偏移量应设置为每次写入之前文件的末尾。
write()
s that are larger than PIPE_BUF
may interleave:
POSIX.1-2008没有说明超过{PIPE_BUF}字节的写请求是否是原子的,但要求{PIPE_BUF}或更少字节的写入必须是原子的。
问:我应该使用哪种替代解决方案同时从父进程和子进程写入文件,而不会使线路无序或重叠?
使用行缓冲模式(1
)打开文件,以清除每行末尾的内部缓冲区 - 它应保留行的近似相对顺序。如果行小于PIPE_BUF
(我的系统上为4096字节),则它们不应该重叠"。
子进程可以将数据写入其标准输出,并且您的父Python进程可以按您喜欢的任何顺序将其写入文件。请参阅how teed_call()
function is implemented。