How to preserve file write order when using threading in python
我有一些python代码来读取文件并将数据推送到列表中。然后把这个列表放到队列中,使用线程处理这个列表,比如说一次20个项目。处理后,我将结果保存到一个新文件中。放入新文件的顺序实际上与原始文件的顺序不同。例如,我输入了,
1 2 3 4 5 | 1 a 2 b 3 c 4 a 5 d |
但是输出看起来是:
1 2 3 4 5 | 2 aa 1 ba 4 aa 5 da 3 ca |
有没有办法保留原来的订单?这是我的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import threading,Queue,time,sys class eSS(threading.Thread): def __init__(self,queue): threading.Thread.__init__(self) self.queue = queue self.lock = threading.Lock() def ess(self,email,code,suggested,comment,reason,dlx_score): #do something def run(self): while True: info = self.queue.get() infolist = info.split('\t') email = infolist[1] code = infolist[2] suggested = infolist[3] comment = infolist[4] reason = infolist[5] dlx_score = (0 if infolist[6] == 'NULL' else int(infolist[6])) g.write(info + '\t' + self.ess(email,code,suggested,comment,reason,dlx_score) +' ') self.queue.task_done() if __name__ =="__main__": queue = Queue.Queue() filename = sys.argv[1] #Define number of threads threads = 20 f = open(filename,'r') g = open(filename+'.eSS','w') lines = f.read().splitlines() f.close() start = time.time() for i in range(threads): t = eSS(queue) t.setDaemon(True) t.start() for line in lines: queue.put(line) queue.join() print time.time()-start g.close() |
我想到了三个想法。对所有人来说,常见的做法是将索引与排队等待处理的数据包一起包含在一起。
- 一种想法是使用控制器/工人/输出框架,在这个框架中,输出线程对工人处理的数据进行去队列、组装和输出。
- 第二种想法是使用内存映射文件进行输出,并使用索引计算写入文件的偏移量(假设写入的长度可能是固定的)。
- 第三种方法是使用索引将处理过的数据放入一个新的列表中,当列表完成时,在末尾而不是在运行中写出项目。