2016-06-30 105 views
0

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

我知道这是为什么:子进程有stdout设置为正常的标准输出,而不是父进程具有的特殊tee对象。我尝试将tee对象作为参数传递给子进程,但我学会了难以将对象作为参数传递给子进程的难题。我的备份计划是传递要写入的文件的路径字符串,然后让子进程使用同一个文件创建自己的TEE对象。

我的问题是,如果两个进程都在同一时间写入同一个文件,输出是否会混乱?我在父进程中使用open(“file”,'w'),并且这首先被调用,并且在子进程中使用open(“file”,'a')。假设文件应该以正确的顺序包含打印语句的输出,因为向文件添加'a'意味着这些行总是被添加到当前文件的结尾,不是吗?还是有规则打开一个文件,防止它被同时打开的两个进程?

POST_TEST:做一些测试自己以后,我发现: - 您才能打开(“文件”,“W”)连续 多次 - 你才能打开(“文件”, 'w'),然后打开(“file”,'a') - 在第一种情况下,子进程完全覆盖文件。 - 在第二种情况下,顺序不正确,某些输出似乎丢失。

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

+0

Google“互斥体”。互斥锁是资源上的MUTually EXCLUSIVE锁,可避免两个进程使用相同资源时发生冲突。 –

+0

http://stackoverflow.com/questions/489861/locking-a-file-in-python –

+1

以“a”模式打开的进程将始终写入文件末尾。但是以'w'模式打开的那个不会。您需要以'a'模式打开它们。 – Barmar

回答

0

谢谢Bamar的建议:使用“a”作为第一个和第二个open()作品。如果您需要为已存在的文件执行此操作,则可以使用file.truncate()在追加文件之前清空该文件。

+0

如果文件以“a”模式打开,则不能保证所有写入都在最后的所有系统上。不保证larges write()是原子的(来自多个进程的输出可能交错)。 – jfs

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

+0

我不介意downvote,但我将不胜感激解释,可以让答案更好。 – jfs

+0

我讨厌它,当人们downvote不说为什么他们这样做 –