使用w模式的python

时间:2016-12-06 19:27:52

标签: python linux file

在linux中,如果我有并行进程使用w / w +模式写入同一文件。 是否有可能将从这两个进程写入的数据混淆。或者它是否总是只在一个进程中包含给定时间的数据,因为w模式会截断现有文件?

3 个答案:

答案 0 :(得分:1)

假设有进程A,进程B将写入相同的文件。 (w / w +模式不是a / a +追加模式)

如果B在A编辑文件后写入文件,A的编辑将消失。

如果A在B编辑文件后写入文件,B的编辑将消失。

如果B在A编辑文件后打开文件,结果取决于您的程序。可能会出现错误,因为A或A的编辑意外编辑可能会再次消失。但是,如果您没有在程序中模仿追加模式,则编辑不会堆叠。

反之亦然。

实际上,最后一位作家将获胜。

你必须要知道,异步处理w / w +模式并不是一个好主意。但是这种“混乱”的情况只能发生在附加模式而不是写入模式上。

How do you append to a file?

答案 1 :(得分:0)

这完全取决于您打开文件的方式以及打开文件的平台。

在Linux / Mac上,文件系统是inode,文件名称只是指向特定的inode。所以如果你有一些像这样的代码:

import time
import threading

def write_one():
    f = open('test.txt', 'w')
    f.write('something longer ')
    time.sleep(0.5)
    f.write(' something more')

def write_two():
    f = open('test.txt', 'w')
    time.sleep(0.1)
    f.write('something shorter')

if __name__ == '__main__':
    t1 = threading.Thread(target=write_one)
    t2 = threading.Thread(target=write_two)

    t1.start()
    t2.start()

    t1.join()
    t2.join()
    print('Done')

将要发生的是一个线程打开文件进行写入,然后当下一个线程打开文件时,它将指向一个新的inode,只需更改文件名所指向的位置。

如果你有这样的代码:

import time                                 
import threading                            

f = open('test.txt', 'w')                   

def write_one():                            
    f.write('something longer ')            
    time.sleep(0.5)                         
    f.write(' something more')              

def write_two():                            
    time.sleep(0.1)                         
    f.write('something shorter')            

if __name__ == '__main__':                  
    t1 = threading.Thread(target=write_one) 
    t2 = threading.Thread(target=write_two) 

    t1.start()                              
    t2.start()                              

    t1.join()                               
    t2.join()                               
    print('Done')   

两个线程都可以访问同一个文件对象。你可能会做一些奇怪的事情,复制可能有效,但我不会依赖它。

但是,如果您使用的是Windows,则第一种方法可能无法正常工作。 Windows并不像一次打开多个进程的文件句柄一样。它会大声抱怨,可能会引发异常。

不要这样做。更好的方法是让一个线程执行IO,如果要写入文件,则另一个线程使用Queue或其他东西将数据发送到IO线程。

答案 2 :(得分:0)

  

在Linux / Mac上,......

     

将要发生的是一个线程打开文件进行写入,然后当下一个线程打开文件时,它将指向一个新的inode,只需更改文件名所指向的位置。

这种说法是错误的,上面的程序可以很容易地纠正以证明是错误的。 如果我们改变了两个

    f = open('test.txt', 'w')

    f = open('test.txt', 'w', 0)

我们不会被输出缓冲欺骗(参见How often does python flush to a file?)并且能够获得

的输出
something shorter something more
test.txt中的

清楚地表明两个open()调用都打开了相同的 inode

  

数据无法在两个线程之间混合?他们总会互相覆盖,对吗?

我们可以看到,这是错误的。