在linux中,如果我有并行进程使用w / w +模式写入同一文件。 是否有可能将从这两个进程写入的数据混淆。或者它是否总是只在一个进程中包含给定时间的数据,因为w模式会截断现有文件?
答案 0 :(得分:1)
假设有进程A,进程B将写入相同的文件。 (w / w +模式不是a / a +追加模式)
如果B在A编辑文件后写入文件,A的编辑将消失。
如果A在B编辑文件后写入文件,B的编辑将消失。
如果B在A编辑文件后打开文件,结果取决于您的程序。可能会出现错误,因为A或A的编辑意外编辑可能会再次消失。但是,如果您没有在程序中模仿追加模式,则编辑不会堆叠。
反之亦然。
实际上,最后一位作家将获胜。
你必须要知道,异步处理w / w +模式并不是一个好主意。但是这种“混乱”的情况只能发生在附加模式而不是写入模式上。
答案 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 。
数据无法在两个线程之间混合?他们总会互相覆盖,对吗?
我们可以看到,这是错误的。