首页 > 编程问答 >Python multiprocessing.connection.Connection 的行为不符合规范

Python multiprocessing.connection.Connection 的行为不符合规范

时间:2024-07-25 07:01:28浏览次数:12  
标签:python python-3.x

根据python规范, recv() python Connection 的方法,(从 multiprocessing.Pipe() 返回,当管道为空且管道的另一端关闭时抛出 EOFError (这里参考: https://docs.python.org/3.9/library/multiprocessing.html#multiprocessing.connection.Connection.recv )

在下面的代码中,我希望子进程在管道关闭后立即退出换句话说,我不会看到很多 still alive! 打印。

import multiprocessing as mp
import sys
import time
from multiprocessing.connection import Connection


def foo(conn: Connection):
    while True:
        try:
            val = conn.recv()
        except EOFError:
            print("no val (got EOFError)")
            return
        print(f"got val {val}")

if __name__ == "__main__":
    print(f"Version: {sys.version}")
    conn_r, conn_w = mp.Pipe(duplex=False)
    proc=mp.Process(target=foo, args=(conn_r,))
    proc.start()
    conn_r.close()
    for i in range(10):
        time.sleep(0.1)
        conn_w.send(i)
    conn_w.close()
    while True:
        if not proc.is_alive():
            break
        proc.join(timeout=0.1)
        print("still alive!")

但这就是我得到的

$ python3 test_pipe.py
Version: 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110]
got val 0
got val 1
got val 2
got val 3
got val 4
got val 5
got val 6
got val 7
got val 8
got val 9
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
still alive!
...

它在你的计算机和Python版本上的表现如何?表明 python 实现中存在错误?


你观察到的行为实际上是预期的,并且没有错误。问题在于对 Connection.recv() 的行为和管道关闭机制的理解。

EOFError 在管道的另一端关闭 并且 管道中没有更多数据时立即引发。但是,你的代码在 conn_w.close() 之前立即发送了 10 条消息。子进程仍在从管道中接收这些消息,并且在收到 EOFError 之前不会耗尽这些消息。

这就是为什么在子进程退出之前会看到多个“still alive!”消息。子进程正在占用时间来处理最后几条消息。

以下是发生的事情的细分:

  1. 父进程创建了一个管道并派生了一个子进程。
  2. 父进程关闭了它的读取器端( conn_r.close() ),并向管道发送了 10 条消息。
  3. 父进程关闭了它的写入器端( conn_w.close() )。 此操作最终将导致 EOFError ,但前提是管道为空。
  4. 子进程接收并打印消息。
  5. 在子进程处理完所有 10 条消息后,它终于在管道上遇到 EOFError 并退出。

为了获得期望的行为,你需要确保在关闭写入器端之前管道为空。 一种方法是在关闭连接之前在父进程中添加一个 conn_w.close() 调用:

    # ... 前面的代码 ...

    for i in range(10):
        time.sleep(0.1)
        conn_w.send(i)
    conn_w.close()  # 这将最终导致 EOFError

    # ... 后面的代码 ...

通过此更改,子进程将在收到所有消息后立即收到 EOFError ,从而导致快速退出并且“still alive!”消息更少。

总之, EOFError 的行为符合预期。该问题源于管道中剩余数据的处理。通过确保在关闭写入器端之前管道为空,你可以实现子进程的预期退出行为。

标签:python,python-3.x
From: 78790887

相关文章

  • 使用 python Flask 发送邮件中的图像
    我想发送一封包含html代码和图像的电子邮件但在gmail中它说图像已附加,我不想要这样,我只想要电子邮件正文中的图像。html_content=f"<imgsrc="cid:banner"alt=""style="width:80%;">"msg=MIMEMultipart('related')html_part=MIMEText(html_c......
  • 在 python requests modul 中,如何检查页面是否使用“POST”方法或“GET”方法
    如何使用python“requests”模块检查页面是否使用“GET”方法或“POST”方法。我期望输出为True或False,或者GET或Post预期代码:importrequestsurl=f"www.get_example.com"response=requests.get(url)ifresponse.check_get==True:print("get")你......
  • VS Code Python - 如果括号(括号、大括号等)未关闭,内联建议不起作用
    我遇到的问题是,当我在未闭合的括号或方括号“内部”开始变量名称时,VSCode将不会显示任何建议。但是,如果在键入变量名称之前闭合括号,则建议效果很好。如果我可以避免它,我宁愿不将自动完成括号关闭设置为True也不使用TabOut扩展。第一个屏幕截图显示建议在闭括号/方......
  • 在 Azure 上部署代码时使用 Python 的多处理模块是否有意义?
    我们的团队在Azure机器学习(AML)上部署了一个Python脚本来处理存储在Azure存储帐户上的文件。我们的管道由一个ForEach活动组成,该活动调用每个或列出的文件的Python脚本。从Azure数据工厂(ADF)运行它会触发多个单独的管道同时运行......
  • 我已成功安装 pypdf2 但无法将其导入到我的 python 文件中
    我已经成功安装了pypdf2模块,但在导入它时,我发现该模块丢失了。我尝试使用fromPyPDF2importPdfReader导入,但它不起作用此问题的各种解决方案是什么?在尝试导入PyPDF2时遇到问题。以下是可能导致此问题的一些常见原因和解决方案:安......
  • Python3打开图片时请求ConnectionResetError(10054)
    我试图从'http://xxx.jpg'之类的网站下载图片。代码:headers={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/66.0.3359.139Safari/537.36'}url='http://xxx.jpg'resp......
  • Jupyter Notebook 环境中的 Python 版本不匹配
    我遇到Jupyter笔记本启动横幅中报告的Python版本与我在笔记本中查询python--version时显示的版本之间的差异。启动横幅指示Python3.11.9,但是当我运行!python--version时,它返回Python3.11.7。我所做的步骤:basecondahas3.11.7versio......
  • Python XML 解析:字符串中的“<”被阻塞
    我有一个使用ET.XMLParser来解析CppCheckXML报告文件的Python模块。当尝试解析字符串中包含“<”的XML元素中的属性之一时,它会令人窒息,它会将其解释为格式错误的XML,例如:<errormsg="Includefile<iostream>notfound.">(注意字符和“iostream”之间的空格必须放......
  • 任意几行代码要成为Python中的函数需要什么?
    我正在上一门计算机科学课,我的任务是创建一个程序来实现一个带有参数的函数。我的老师告诉我,下面的代码不是一个函数,这让我很困惑,对于将某些代码行归类为“函数”所需的条件,我感到很困惑。defgame(numbers,max_turns,pfl,tgl):turns=0flag=Falseprint("You......
  • 如何使用 Python 创建新的 Azure 订阅?
    我正在尝试使用PythonSDK以编程方式创建新的Azure订阅。我发现的对AzurePythonSDK的唯一引用是这个这是我最终得到的结果:importazure.mgmt.billingimportazure.mgmt.subscriptioncreds=AzureCliCredential()client_name='test'defcreat......