簡體   English   中英

用Python多處理文件,然后將結果寫入磁盤

[英]Multiprocessing a file in Python, then writing the result to disk

我要執行以下操作:

  • 從csv文件讀取數據
  • 處理所述csv的每一行(假設這是一個長時間的網絡操作)
  • 將結果寫入另一個文件

我嘗試將這個這個答案結合在一起,但收效甚微。 第二個隊列的代碼永遠不會被調用,因此不會發生磁盤寫操作。 如何讓進程知道第二個隊列?

請注意,我並不需要multiprocessing 如果async / await效果更好,我全力以赴。

到目前為止我的代碼

import multiprocessing
import os
import time

in_queue = multiprocessing.Queue()
out_queue = multiprocessing.Queue()

def worker_main(in_queue, out_queue):
    print (os.getpid(), "working")
    while True:
        item = in_queue.get(True)
        print (os.getpid(), "got", item)
        time.sleep(1) #long network processing
        print (os.getpid(), "done", item)
        # put the processed items to be written to disl
        out_queue.put("processed:" + str(item))


pool = multiprocessing.Pool(3, worker_main,(in_queue,out_queue))

for i in range(5): # let's assume this is the file reading part
    in_queue.put(i)

with open('out.txt', 'w') as file:

    while not out_queue.empty():
        try:
            value = q.get(timeout = 1)
            file.write(value + '\n')
        except Exception as qe:
            print ("Empty Queue or dead process")

我在嘗試執行您的代碼時遇到的第一個問題是:

An attempt has been made to start a new process before the current process has finished 
its bootstrapping phase. This probably means that you are not using fork to start your 
child processes and you have forgotten to use the proper idiom in the main module

我必須將所有模塊作用域指令包裝在if __name__ == '__main__':慣用語中。 在這里閱讀更多

因為您的目標是遍歷文件的各行, Pool.imap()似乎很合適。 imap()文檔引用了map()文檔,不同之處在於imap()懶惰地從可迭代對象(在您的情況下為csv文件)中提取下一個項目,如果csv文件很大,這將是有益的。 因此,從map()文檔中:

此方法將可迭代項分為多個塊,將其作為單獨的任務提交給流程池。

imap()返回一個迭代器,因此您可以對流程工作者產生的結果進行迭代,以對它們進行處理(在您的示例中,是將結果寫入文件中)。

這是一個工作示例:

import multiprocessing
import os
import time


def worker_main(item):
    print(os.getpid(), "got", item)
    time.sleep(1) #long network processing
    print(os.getpid(), "done", item)
    # put the processed items to be written to disl
    return "processed:" + str(item)


if __name__ == '__main__':
    with multiprocessing.Pool(3) as pool:
        with open('out.txt', 'w') as file:
            # range(5) simulating a 5 row csv file.
            for proc_row in pool.imap(worker_main, range(5)):
                file.write(proc_row + '\n')

# printed output:
# 1368 got 0
# 9228 got 1
# 12632 got 2
# 1368 done 0
# 1368 got 3
# 9228 done 1
# 9228 got 4
# 12632 done 2
# 1368 done 3
# 9228 done 4

out.txt看起來像這樣:

processed:0
processed:1
processed:2
processed:3
processed:4

注意,我也不必使用任何隊列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM