あなたが行の途中で同じ行または新しい行にごちゃ混ぜにテキストを見たことがないという事実は、あなたが実際にファイルに追加シンクロする必要がいけないの手がかりです。問題は、printを使用して単一のファイルハンドルに書き込むことです。私はprint
が実際には1つの呼び出しでファイルハンドルに2つの操作を行っていると思われ、それらの操作はスレッド間で競合しています。基本的にprint
は何かやっている:
file_handle.write('whatever_text_you_pass_it')
file_handle.write(os.linesep)
を、別のスレッドが同じファイルハンドルに同時にこれをやっているので、時には1つのスレッドが最初の書き込みになりますし、他のスレッドは、その最初の書き込みになりますと、あなた2つのキャリッジリターンが連続して得られます。またはこれらの本当に任意の順列。
これを回避する最も簡単な方法は、print
の使用をやめ、そのままwrite
を使用することです。
output.write(f + os.linesep)
これはまだ私にとって危険だと思われます。私は、同じファイルハンドルオブジェクトを使用し、その内部バッファのために競合するすべてのスレッドで何が期待できるのかわかりません。個人的には問題はすべての問題を解決し、すべてのスレッドが独自のファイルハンドルを取得するようにします。ライトバッファフラッシュのデフォルトはラインバッファであるため、ファイルがフラッシュされるときにはos.linesep
で終了するため、これが機能することにも注意してください。それを強制的にラインバッファを使用するようにの3番目の引数として1
を送信します。あなたはこのようにそれをテストすることができます
#!/usr/bin/env python
import os
import sys
import threading
def hello(file_name, message, count):
with open(file_name, 'a', 1) as f:
for i in range(0, count):
f.write(message + os.linesep)
if __name__ == '__main__':
#start a file
with open('some.txt', 'w') as f:
f.write('this is the beginning' + os.linesep)
#make 10 threads write a million lines to the same file at the same time
threads = []
for i in range(0, 10):
threads.append(threading.Thread(target=hello, args=('some.txt', 'hey im thread %d' % i, 1000000)))
threads[-1].start()
for t in threads:
t.join()
#check what the heck the file had
uniq_lines = set()
with open('some.txt', 'r') as f:
for l in f:
uniq_lines.add(l)
for u in uniq_lines:
sys.stdout.write(u)
出力は次のようになります。
hey im thread 6
hey im thread 7
hey im thread 9
hey im thread 8
hey im thread 3
this is the beginning
hey im thread 5
hey im thread 4
hey im thread 1
hey im thread 0
hey im thread 2
ポストいくつかのコードを、それが役立つだろう。 –
新しい行を追加します。 – Kuf
* impossibru *のようなサウンド。 – plaes