簡體   English   中英

Python 3 multiprocessing.Process里面的類?

[英]Python 3 multiprocessing.Process inside class?

我有一些復雜的A類計算數據(大型矩陣計算),同時消耗B類的輸入數據。

A本身使用多個核心。 但是,當A需要下一個數據塊時,它會等待相當長的一段時間,因為B在同一個主線程中運行。

由於A主要使用GPU進行計算,我想讓B在CPU上同時采集數據。

我的最新方法是:

# every time *A* needs data
def some_computation_method(self):
    data = B.get_data()
    # start computations with data

......和B看起來大致相同:

class B(object):

    def __init__(self, ...):
        ...
        self._queue = multiprocessing.Queue(10)
        loader = multiprocessing.Process(target=self._concurrent_loader)

    def _concurrent_loader(self):
        while True:
            if not self._queue.full():
                # here: data loading from disk and pre-processing
                # that requires access to instance variables
                # like self.path, self.batch_size, ...
                self._queue.put(data_chunk)
            else:
                # don't eat CPU time if A is too busy to consume
                # the queue at the moment
                time.sleep(1)

    def get_data(self):
        return self._queue.get()

這種方法可以被視為“pythonic”解決方案嗎?

由於我對Python的多處理模塊沒有多少經驗,所以我構建了一個簡單/簡單的方法。 然而,它對我來說看起來有點“hacky”。

什么是更好的解決方案讓B類同時從磁盤加載數據並通過某個隊列提供它,而主線程運行繁重的計算並不時從隊列中消耗數據?

雖然你的解決方案完全沒問題,特別是對於“小型”項目,但它具有與B類緊密結合的線程的缺點。 因此,如果您(例如)由於某種原因想要以線程方式使用B ,那么您的運氣不好。

我會以線程安全的方式親自編寫類,然后使用外部的線程調用它:

class B(object):
    def __init__(self):
        self._queue = multiprocessing.Queue(10)

    ...

if __name__ == '__main__':
    b = B()

    loader = multiprocessing.Process(target=b._concurrent_loader)
    loader.start()

這使B更靈活,更好地分離依賴關系並且更容易測試。 它通過顯式創建線程使代碼更具可讀性,與在類創建時隱式發生相比。

暫無
暫無

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

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