簡體   English   中英

python多重處理,為每個進程創建實例並重用它

[英]python multiprocessing, make instance per process and reuse it

我正在使用pytesseract通過多處理方法進行一些ocr。

該方法如下所示:

tess_api = PyTessBaseAPI()
Parallel(n_jobs=4)(delayed(execute)(image) for image in images)

具有以下功能:

def execute(image):
    tess_api.SetImage(image)
    text = tess_api.GetUTF8Text()

這將導致並發問題,因為在工作程序2執行gettext()之前,工作程序1可能會覆蓋映像。

現在的想法是讓每個工人擁有一個PyTessBaseAPI實例。 主要的想法是做類似的事情:

tess_apis = [PyTessBaseAPI(), PyTessBaseAPI(), PyTessBaseAPI(), PyTessBaseAPI()]

然后將tess_api[0]給工作程序0,但我不知道如何在工作程序和實例之間建立連接。 有什么建議,或者什么是更好的方法? 因為我有成千上萬張圖像,所以我不想在execute函數中創建實例。

在每個工作進程開始讀取其工作隊列之前,使用Pool(initializer=...)初始化Tesseract對象一次。

tess_api = None

def initialize_worker():
    global tess_api
    tess_api = PyTessBaseAPI()  # initialize a copy for this instance

def execute(image):
    tess_api.SetImage(image)
    text = tess_api.GetUTF8Text()

def main():
    with multiprocessing.Pool(initializer=initialize_worker) as p:
        for result in p.imap_unordered(images, chunksize=10):
            # ...

這僅在您使用實際流程時才有效; 如果您使用的是線程(考慮到Tesseract是C並會發布GIL,這可能會起作用),則可以使用contextvars / threading.local

Pool(initializer=...)可以如上所述。 但是,如果您想做更復雜的事情,建議您使用Ray

然后可以表示如下。

import ray

ray.init()

@ray.remote
class Worker(object):
    def __init__(self):
        self.tess_api = PyTessBaseAPI()

    def execute(self, image):
        self.tess_api.SetImage(image)
        return self.tess_api.GetUTF8Text()

# Create several Worker actors.
workers = [Worker.remote() for _ in range(4)]

# Execute tasks on them in parallel.
result_ids = [worker.execute.remote(image) for worker in workers]

# Get the results
results = ray.get(result_ids)

您可以在文檔中閱讀有關Ray的更多信息。 請注意,我幫助開發Ray。

暫無
暫無

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

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