使用Plotlys“ write_image”功能存储子流程中的静态图像时,Orca流程不会关闭

问题描述

在我的程序中,我将熊猫数据帧传递给multiprocessing.Pool个工人。然后,每个工作人员创建一个可绘制的图形,并通过fig.write_image("img_name")将其存储在磁盘上。

如果我使用orca引擎fig.write_image(name,engine="orca")来存储图像,则由orca引擎创建的子进程将永远不会关闭,并且一段时间后,我开始出现与此issue相同的错误

我发现使用kaleido引擎不会出现此问题。下面是重现该问题的代码。要查看在主python进程完成后仍有多少个进程在运行,请在终端中打开htop并按F4并键入 orca 来过滤该进程。

有人知道这是orca的已知问题,还是我在多处理代码中做错了事。

要运行代码,您需要在当前工作路径中创建目录test_images_2/

Orca版本:plotly-orca 1.3.1

# General imports
import multiprocessing
import os
import time
import psutil
import pandas as pd
import random
import plotly.express as px
import plotly
import queue
# Project specific imports

# Imports from internal libraries

# Typing imports
from typing import TYPE_CHECKING


# if TYPE_CHECKING:

def rand_data_gen(size):
    df = pd.DataFrame(
        dict([(x,[random.random() for _ in range(size)]) for x in range(size)])
    )
    return df


def work_2(qe):
    item = qe.get(True)
    qdf = item[0]
    name = item[1]
    print(os.getpid(),"got",name)
    fig = px.imshow(qdf)
    fig.write_image(name)
    return True


def worker_main(qe):
    print(os.getpid(),"working")
    while True:
        item = qe.get(True)
        qdf = item[0]
        name = item[1]
        print(os.getpid(),name)

        fig = px.imshow(qdf)
        fig.write_image(name,engine="orca")


if __name__ == '__main__':
    print(f'Running {__file__}')
    print(f"Script dir:  {os.path.dirname(os.path.abspath(__file__))}")
    print(f"Working dir: {os.path.abspath(os.getcwd())}")
    print(f"System memory: {psutil.virtual_memory()}")

    save_path = "test_images_2/"

    end_evt = multiprocessing.Event()
    the_queue = multiprocessing.Queue()

    the_pool = multiprocessing.Pool(5,worker_main,(the_queue,))
    # the_pool = multiprocessing.Pool(5,work_2,))
    i = 0
    for i in range(100):
        df = rand_data_gen(100)
        i += 1
        the_queue.put((df,f"{save_path}image{i}.png"))
        print(the_queue.qsize())

    count_sleep = 0

    while not the_queue.empty():
        count_sleep += 1
        print(f"\rWaiting for que to be empty: {count_sleep}",end="")
        time.sleep(1)

    end_evt.set()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...