Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中使用线程时如何保持文件写入顺序_Python_Python Multithreading - Fatal编程技术网

在python中使用线程时如何保持文件写入顺序

在python中使用线程时如何保持文件写入顺序,python,python-multithreading,Python,Python Multithreading,我有一些python代码来读取文件并将数据推送到列表中。然后将该列表放入队列,使用线程处理该列表,比如说一次处理20个项目。处理后,我将结果保存到一个新文件中。新文件中的内容实际上与原始文件的顺序不同。例如,我有输入 1 a 2 b 3 c 4 a 5 d 1A 2 b 3 c 4A 5d 但输出结果如下所示: 2 aa 1 ba 4 aa 5 da 3 ca 2 aa 1

我有一些python代码来读取文件并将数据推送到列表中。然后将该列表放入队列,使用线程处理该列表,比如说一次处理20个项目。处理后,我将结果保存到一个新文件中。新文件中的内容实际上与原始文件的顺序不同。例如,我有输入

1 a 2 b 3 c 4 a 5 d 1A 2 b 3 c 4A 5d 但输出结果如下所示:

2 aa 1 ba 4 aa 5 da 3 ca 2 aa 1 ba 4 aa 5 da 3 ca 有没有办法保持原来的秩序? 这是我的密码:

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) +'\r\n') 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() 导入线程、队列、时间、系统 eSS类(线程。线程): 定义初始化(自我,队列): threading.Thread.\uuuuu init\uuuuuu(自) self.queue=队列 self.lock=threading.lock() 定义(自我、电子邮件、代码、建议、评论、原因、dlx_分数): #做点什么 def运行(自): 尽管如此: info=self.queue.get() infolist=info.split('\t') 电子邮件=信息列表[1] 代码=信息列表[2] 建议=信息列表[3] 注释=信息列表[4] 原因=信息列表[5] dlx_分数=(如果信息列表[6]='NULL'else int(信息列表[6]),则为0) g、 写(信息+'\t'+self.ess(电子邮件、代码、建议、评论、原因、dlx_分数)+'\r\n') self.queue.task_done() 如果名称=“\uuuuu main\uuuuuuuu”: queue=queue.queue() filename=sys.argv[1] #定义线程数 线程数=20 f=打开(文件名为'r') g=打开(文件名+'.eSS',w') lines=f.read().splitlines() f、 关闭() 开始=时间。时间() 对于范围内的i(线程): t=eSS(队列) t、 setDaemon(True) t、 开始() 对于行中的行: 队列.放置(行) queue.join() 打印时间。时间()-开始 g、 关闭()
我想到了三个想法。所有的共同点是在排队等待处理的数据包中包含一个索引

  • 然后,一种想法是使用controller/workers/output框架,在该框架中,输出线程对worker处理的数据进行解队列、组装和输出
  • 第二种想法是使用内存映射文件进行输出,并使用索引计算写入文件的偏移量(假设可能是固定长度的写入)
  • 第三种方法是使用索引将处理过的数据放入一个新的列表中,当列表完成时,在末尾而不是在运行中写出项目

    • 我想到了三个想法。所有的共同点是在排队等待处理的数据包中包含一个索引

      • 然后,一种想法是使用controller/workers/output框架,在该框架中,输出线程对worker处理的数据进行解队列、组装和输出
      • 第二种想法是使用内存映射文件进行输出,并使用索引计算写入文件的偏移量(假设可能是固定长度的写入)
      • 第三种方法是使用索引将处理过的数据放入一个新的列表中,当列表完成时,在末尾而不是在运行中写出项目

      “有些人在遇到问题时会想,“我知道,我会使用线程”,然后两个线程就没有了问题。”(Ned Batchelder)lol nice重新调整了引用:)不使用队列怎么样?您可以让每个线程处理原始列表的特定索引,然后将结果放在同一索引的新列表中。重新加入线程,然后从主线程写入。。。或者看看信号量和互斥量,你的代码甚至不会按原样运行。变量
      g
      不在run方法的作用域中。此外,正如丹尼尔所暗示的,你真的需要线吗?即使忽略了无序信息,这是否真的比按顺序读写更快?“有些人在遇到问题时会想,“我知道,我会使用线程”,然后两个线程都没有问题。”(Ned Batchelder)lol nice重新调整了引用:)不使用队列怎么样?您可以让每个线程处理原始列表的特定索引,然后将结果放在同一索引的新列表中。重新加入线程,然后从主线程写入。。。或者看看信号量和互斥量,你的代码甚至不会按原样运行。变量
      g
      不在run方法的作用域中。此外,正如丹尼尔所暗示的,你真的需要线吗?即使忽略了无序信息,这是否真的比按顺序读写要快?取下第三个项目符号,添加一个计数器,然后在末尾写入。谢谢。拿走你的第三颗子弹,加上一个计数器,然后在最后写下。谢谢