win11 python3.10环境进程通信执行状况及相关问题

win11 python3.10环境进程通信执行状况及相关问题

下面这段代码在  win11  python3.10环境  不会报错

有一个问题:没有recv.join(),主进程无法正常关闭的原因是什么?


完整代码

# coding:utf-8

"""
这段代码演示了如何使用 Python 的 multiprocessing 模块创建一个进程池,并使用进程池执行多个函数。
具体来说,代码中定义了一个名为 Work 的类,该类用于封装发送和接收消息的过程。其中,send() 方法用于向队列中发送消息,
send_all() 方法用于向队列中发送多个消息,receive() 方法用于从队列中接收消息。在构造函数中,将队列对象传入。
在主程序中,首先创建了一个队列 q,然后创建了一个 Work 实例 work,将队列对象传入构造函数中。接着创建两个子进程 send 和 recv,
分别用于向队列中发送消息和接收消息。最后启动子进程 send 和 recv。
在 send 进程中,循环调用 work.send() 方法,向队列中发送多个消息。在 receive 进程中,循环调用 work.receive() 方法,从队列中接收消息并打印出来。
最后,等待子进程执行完毕后,调用 terminate() 方法来终止 receive 进程。
"""

import time
import json
import multiprocessing


class Work(object):
    def __init__(self, q):
        self.q = q

    def send(self, message):
        if not isinstance(message, str):
            message = json.dumps(message)
        self.q.put(message)

    def send_all(self):
        for i in range(3):
            self.q.put(i)
            time.sleep(1)

    def receive(self):
        while 1:
            result = self.q.get()
            try:
                res = json.loads(result)
            except:
                res = result
            print('recv is %s' % res)


if __name__ == '__main__':
    q = multiprocessing.Queue()
    work = Work(q)
    send = multiprocessing.Process(target=work.send, args=({'name': '小慕'},))
    recv = multiprocessing.Process(target=work.receive)
    # send_all_p = multiprocessing.Process(target=work.send_all)

    # send_all_p.start()
    send.start()
    # time.sleep(2)  # 接收时间和发送时间不同步,只要进程不关闭信息并不会丢失
    recv.start()

    # send.join()  # 在send执行完成前阻塞主进程
    # send.close()  # send.close()必须在join之前,这样才能关闭执行完成的send。否则如果此时send还在执行中,将报错
    # # send.start()  # send.close()以后就不能重新start()了
    # send_all_p.join()  #
    # recv.terminate()  # 由于recv进程(接收进程)没有终止,导致主程序一直等待中无法关闭,
    # 所以在 发送进程执行时间最长的 进程执行join阻塞主进程,待所有发送进程执行完毕后执行recv.terminate()强行关闭recv进程
    # 此时主进程可以顺利结束


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
Mr朱_ 提问者 2023-05-28 10:40:00

上面问题提错了,是没有recv.terminate(),主进程无法正常关闭的原因是什么?

之前课程讲到主进程关闭会连带关闭子进程,在这里主进程为什么必须要等待子进程关闭才能关闭

通信中间的锁是起到保护子进程不被关闭的原因吗?

  • 同学,你好!1、因为recv函数中while 1:循环一直执行等待接收队列中的数据,无法结束。最后使用reve.terminate()强制结束进程

    2、主进程等子进程关闭,recevie子进程是while 1 无线循环的,若要不结束子进程,程序一值无线循环,程序不会结束,所以先关闭子进程。

    https://img1.sycdn.imooc.com//climg/6474147e091e83ad11790624.jpg

    https://img1.sycdn.imooc.com//climg/6474162e098bccb111140560.jpg

    3、代码码中未涉及锁,同学若想研究底层代码,可以自己扩展知识,研究下底层代码



    祝学习愉快~

    2023-05-29 11:06:26
  • 提问者 Mr朱_ 回复 好帮手慕小猿 #2

    底层代码相关资料在哪获取,是用c写的吗?

    老师帮忙提供一下相关方向,谢谢

    2023-05-30 08:32:41
  • 好帮手慕小猿 回复 提问者 Mr朱_ #3

    同学,你好!Cpython 是用C语言所编写的,python 中的线程也是python的一部分,也是C写的。

    2、同学可按住ctrl 键,鼠标点击方法,进入方法查看方法的功能,了解下底层的源码。若是想了解C调用python 可搜下“源码探秘 CPython”看是否满足同学需求

    祝学习愉快~

    2023-05-30 11:30:12
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师