首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多处理BrokenPipeError:[WinError 232]使用.send()方法时管道正在关闭

多处理BrokenPipeError:[WinError 232]使用.send()方法时管道正在关闭
EN

Stack Overflow用户
提问于 2022-10-12 07:35:57
回答 2查看 66关注 0票数 0

我目前正在开发一个使用在线OCR的程序。这个API需要2到5秒的时间才能发送给我一个处理过的图像,所以用户可以开始处理第一个图像,而其他的则是使用multiprocessing在不同的python实例上处理,而不是让用户等待所有的图像被处理。我一直在使用multiprocessing.Pipe()来回发送值。守则如下:

代码语言:javascript
运行
复制
import multiprocessing as mp
# importing cv2, PIL, os, json, other stuff

def image_processor():
    # processes the first image in the list, then moves the remaining images to a different python instance:
    p_conn, c_conn = mp.Pipe()
    p = mp.Process(target=Processing.worker, args=([c_conn, images, path], 5))
    p.start()
    
    while True:
        out = p_conn.recv()
        if not out:
            break
        else:
            im_data.append(out)
            p_conn.send(True)


class Processing:
    def worker(data, mode, headers=0):
        # (some if statements go here)
        elif mode == 5:
            print(data[0])
            for im_name in data[1]:
            if data[1].index(im_name) != 0:
                im_path = f'{data[2]}\{im_name}'  # find image path
                im = pil_img.open(im_path).convert('L')  # open and grayscale image with PIL
                os.rename(im_path, f'{data[2]}\Archive\{im_name}')  # move original to archive
                im_grayscale = f'{data[2]}\g_{im_name}'  # create grayscale image path
                im.save(im_grayscale)  # save grayscale image
                    
                ocr_data = json.loads(bl.Visual.OCR.ocr_space_file(im_grayscale)).get('ParsedResults')[0].get('ParsedText').splitlines()
                print(ocr_data)
                data[0].send([im_name, f'{data[2]}\Archive\{im_name}', ocr_data])
                data[0].recv()
            
            data[0].send(False)

这给我留下了以下的回溯:

代码语言:javascript
运行
复制
Process Process-1:
Traceback (most recent call last):
  File "C:\Users\BruhK\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Users\BruhK\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "c:\Users\BruhK\PycharmProjects\pythonProject\FleetFeet-OCR-Final.py", line 275, in worker
    data[0].send([{im_name}, f'{data[2]}\Archive\{im_name}', ocr_data])
  File "C:\Users\BruhK\AppData\Local\Programs\Python\Python310\lib\multiprocessing\connection.py", line 211, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "C:\Users\BruhK\AppData\Local\Programs\Python\Python310\lib\multiprocessing\connection.py", line 285, in _send_bytes
    ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True)
BrokenPipeError: [WinError 232] The pipe is being closed

注意,从子函数发送给父函数的数据是一个2d或3d数组。在测试中,我能够在子函数和父函数之间来回发送2d和3d数组。

用于测试的代码示例如下:

代码语言:javascript
运行
复制
import multiprocessing as mp
import random
import time


def hang(p):
  hang_time = random.randint(1, 5)
  time.sleep(hang_time)
  print(p)
  p.send(hang_time)
  time.sleep(1)


class Child:
  def process():
    start = time.time()
    p_conn, c_conn = mp.Pipe()
    p = mp.Process(target=hang, args=(c_conn,))
    p.start()
    out = p_conn.recv()
    print(f'Waited for {time.time() - start}')
    p.join()
    print(f'New time: {time.time() - start}')
    return out


class Parent:
  def run():
    # do some stuff
    
    print(f'Hang time: {Child.process()}')
    
    # do some stuff


if __name__ == '__main__':
  Parent.run()

我该如何解决这个问题?是否需要更多的信息?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-13 07:28:24

它看起来您的缩进是错误的: data.send( False )在for循环中,所以它在处理第一个图像后发送False,并且您的主进程退出时间(True)

票数 1
EN

Stack Overflow用户

发布于 2022-10-13 01:03:37

正如@tturbo所指出的,代码data[0].send(False)位于它应该在外部的for循环中,这就阻止了中断的管道错误。我不知道为什么要解决这个问题,如果其他人愿意把它弄清楚的话,我请客。对我来说,重要的是它成功了。谢谢。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74038087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档