簡體   English   中英

如何使用多重處理寫入HDF5文件?

[英]How to write in HDF5 file using multiprocessing?

所以在我的代碼中,我有這樣的東西:

import tables
import bson

def proc():
    data = bson.decode_file_iter(open('file.bson'), 'rb'))
    atom = tables.Float64Atom()
    f = tables.open_file('t.hdf5', mode='w')
    array_c = f.create_earray(f.root, 'data', atom, (0, m))

    for c,d in enumerate(data):
        for e,p in enumerate(d['id']):
            x = some_array1bym()
            array_c.append(x)

     f.close()

這很好用,但是我想通過多處理來解決這個問題,因為我對此並不陌生,我不知道該怎么做,我發現了這樣的東西:

def proc():
    NCORE = 6               
    data = bson.decode_file_iter(open('file.bson'), 'rb'))
    atom = tables.Float64Atom()
    f = tables.open_file('t.hdf5', mode='w')
    array_c = f.create_earray(f.root, 'data', atom, (0, m))

    def process(q, iolock):
        while True:
           d = q.get()
           if d is None:
               break
           for e, p in enumerate(d['id']):
               x = some_array1bym()
               array_c.append(x)

     q = mp.Queue(maxsize=NCORE)
     iolock = mp.Lock()
     pool = mp.Pool(NCORE, initializer=process, initarg=(q,iolock))

     for c,d in enumerate(data):
        q.put(d)

     for _ in range(NCORE):
         q.put(None)
     pool.close()
     pool.join()

     f.close()

但是,這給了我一個空文件。

有人可以幫忙嗎?

謝謝!

您誤解了multiprocessing.Pool 初始化Pool它將啟動N工作進程。 initializer參數只是一個在啟動時在每個工作進程上運行一次的函數。 流程稍后將執行此任務。 然后,您使用Pool.mapPool.apply類的方法(或其異步補碼)將作業實際提交到池中進行處理。

我認為問題可能與array_c變量有關。 在分叉池之后,每個工作人員將獲得此變量的副本 這將導致a)這些array_c副本中的每個副本array_c將嘗試寫入hdf5文件,從而給出未定義的結果,或者b)僅當f.close()時,主進程中的副本為空,才將其寫入文件。 f.close()被調用。 我不確定哪個不熟悉pytables的內部pytables

array_c相反, qiolock在所有工作線程和主線程之間共享。 q是一個mp.Queue實例,而iolock是一個mp.Lock實例,這些類經過特殊設計,可以一次被多個進程使用。 我認為pytables類並非如此。

您應該使用mp.Lock實例來確保一次只有一個進程寫入文件。 我認為您需要做的是將process功能修改為以下內容:

def process(q, iolock):
    while True:
        d = q.get()
        if d is None:
            break
        for e, p in enumerate(d['id']):
            x = some_array1bym()
            # acquire lock to ensure only one process writes data at once
            iolock.acquire()
            # get new handle to hdf5 file in append mode
            f = tables.open_file('t.hdf5', mode='a')
            # get new handle to data set and append new data
            array_c = tables.EArray(f.root, 'data')
            array_c.append(x)
            # close file and release lock to allow another process to write
            f.close()
            iolock.release()

暫無
暫無

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

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