鱼C论坛

 找回密码
 立即注册
查看: 1470|回复: 16

[已解决]多进程这个要怎么理解?

[复制链接]
发表于 2020-8-5 08:48:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import multiprocessing as mp
import os

# Run phase
def v():
    print('Run', os.getpid())
    print(__name__, os.getpid())

# Initialization phase
print('Initialize', os.getpid(), os.getpid())
print(__name__, os.getpid(), os.getpid())

if __name__ == '__main__':
    # start a new Process to execute function `v` and wait for it
    p = mp.Process(target=v)
    p.start()
    p.join()
输出:
Initialize 9836 9836
__main__ 9836 9836
Initialize 14084 14084
__mp_main__ 14084 14084
Run 14084
__mp_main__ 14084

为什么会执行两次函数外的打印? 而且两次的__name__还不相同?



最佳答案
2020-8-5 17:50:57
本帖最后由 全能小乌贼 于 2020-8-5 22:38 编辑

个人认为是因为你的前两个print('Initialize', os.getpid(), os.getpid())和print(__name__, os.getpid(), os.getpid())并没有定义一个函数,因此当程序执行的时候是从上到下走的,所以开始先打印Initialize 9836 9836和__main__ 9836 9836,注意这里的name == __main__,但是当执行完成后,开始执行if name== "__main__"下面的语句时,你使用了多进程,然后你的mp.Process创建了一个子进程,但是还有一个默认的主进程,所以主进程会第一时间将整个程序从上到下执行,因为那两行没有写在一个函数内,所以又会被执行一边,可以从打印出来的名字中看出一二,Initialize 14084 14084和__mp_main__ 14084 14084,这里的name == __mp_main__, 其中的mp代表的是多进程实例之后产生的父(主)进程执行的。

楼主如果还不懂欢迎继续提问,你的好评是我回答问题的动力。:)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-5 09:59:53 | 显示全部楼层
子进程会导入父进程脚本,所以不在if __name__ == '__main__'下面的会再次被执行。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-5 10:57:14 | 显示全部楼层
suchocolate 发表于 2020-8-5 09:59
子进程会导入父进程脚本,所以不在if __name__ == '__main__'下面的会再次被执行。

能详细说一下么?感谢大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-5 11:02:26 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-5 11:11:07 | 显示全部楼层
看的是 一脸懵逼啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-5 13:48:33 | 显示全部楼层
我也不懂进程(有气无力)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-5 17:50:57 | 显示全部楼层    本楼为最佳答案   
本帖最后由 全能小乌贼 于 2020-8-5 22:38 编辑

个人认为是因为你的前两个print('Initialize', os.getpid(), os.getpid())和print(__name__, os.getpid(), os.getpid())并没有定义一个函数,因此当程序执行的时候是从上到下走的,所以开始先打印Initialize 9836 9836和__main__ 9836 9836,注意这里的name == __main__,但是当执行完成后,开始执行if name== "__main__"下面的语句时,你使用了多进程,然后你的mp.Process创建了一个子进程,但是还有一个默认的主进程,所以主进程会第一时间将整个程序从上到下执行,因为那两行没有写在一个函数内,所以又会被执行一边,可以从打印出来的名字中看出一二,Initialize 14084 14084和__mp_main__ 14084 14084,这里的name == __mp_main__, 其中的mp代表的是多进程实例之后产生的父(主)进程执行的。

楼主如果还不懂欢迎继续提问,你的好评是我回答问题的动力。:)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-6 12:19:43 | 显示全部楼层
本帖最后由 bangbang-ande 于 2020-8-6 12:21 编辑

我觉得应该是这样的:
首先主进程执行了:
# Initialization phase
print('Initialize', os.getpid(), os.getpid())
print(__name__, os.getpid(), os.getpid())
然后执行了之后就进入判断是否是主进程
接着生成子进程,进行执行
而子进程同时执行了两个部分:
1:v函数:
def v():
    print('Run', os.getpid())
    print(__name__, os.getpid())
2:# Initialization phase
# Initialization phase
print('Initialize', os.getpid(), os.getpid())
print(__name__, os.getpid(), os.getpid())
但由于时间原因,所以看到的次序反过来了,先看到了2的结果,然后看到1的结果(2和1指上边两段程序)
而处理方法是直接把
# Initialization phase
print('Initialize', os.getpid(), os.getpid())
print(__name__, os.getpid(), os.getpid())
移到
if __name__ == '__main__':
    # 把Initialization phase这段代码移到这
    p = mp.Process(target=v)
    p.start()
    p.join()
里边


就应该是这样:
import multiprocessing as mp
import os



# Run phase
def v():
    print('Run', os.getpid())
    print(__name__, os.getpid())

# Initialization phase

if __name__ == '__main__':
    print('Initialize', os.getpid(), os.getpid())
    print(__name__, os.getpid(), os.getpid())
    # start a new Process to execute function `v` and wait for it
    p = mp.Process(target=v)
    p.start()
    p.join()
(我没学那么透,但分析了代码,应该是这样。。。)

没错的话记得设置为最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-7 13:57:54 | 显示全部楼层
bangbang-ande 发表于 2020-8-6 12:19
我觉得应该是这样的:
首先主进程执行了:

看到你这个解释我才想起来我还是会点基础的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-9 15:28:43 | 显示全部楼层
全能小乌贼 发表于 2020-8-5 17:50
个人认为是因为你的前两个print('Initialize', os.getpid(), os.getpid())和print(__name__, os.getpid(),  ...

是不是在创建子进程mp.Process(target=v)时候,会默认创建一个新的主进程,就是将原来的__main__主进程进行改变,变成__mp_main__,然后这个新主进程会再执行一遍,不知道我这样理解对不对?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-9 15:30:28 | 显示全部楼层
全能小乌贼 发表于 2020-8-5 17:50
个人认为是因为你的前两个print('Initialize', os.getpid(), os.getpid())和print(__name__, os.getpid(),  ...


刚刚想到一个问题,就是再创建线程时,不能再start()方法后面直接join(),这个是为什么?大佬知道么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-9 18:03:44 | 显示全部楼层
弱弱的佳佳 发表于 2020-8-9 15:28
是不是在创建子进程mp.Process(target=v)时候,会默认创建一个新的主进程,就是将原来的__main__主进程进 ...

对,是这个意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-9 18:07:50 | 显示全部楼层
弱弱的佳佳 发表于 2020-8-9 15:30
刚刚想到一个问题,就是再创建线程时,不能再start()方法后面直接join(),这个是为什么?大佬知道么?

线程这个东西我没仔细了解过,个人人为线程没有必要细致地了解,使用多进程是一定会增加运行速度的,但是线程使用一般并不会增加速度,而且如果你使用的不恰当反倒会降低运行速度,没有成为高手之前线程还是放一放吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-10 13:59:08 | 显示全部楼层
全能小乌贼 发表于 2020-8-9 18:07
线程这个东西我没仔细了解过,个人人为线程没有必要细致地了解,使用多进程是一定会增加运行速度的,但是 ...

明白!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-10 13:59:57 | 显示全部楼层
bangbang-ande 发表于 2020-8-6 12:19
我觉得应该是这样的:
首先主进程执行了:

十分感谢大佬的回答,收益颇深!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-8-10 15:42:56 | 显示全部楼层
弱弱的佳佳 发表于 2020-8-10 13:59
十分感谢大佬的回答,收益颇深!

并不是大佬,我不是计算机专业的,也是半路出家,一起加油学习把!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-11 20:04:02 | 显示全部楼层
全能小乌贼 发表于 2020-8-10 15:42
并不是大佬,我不是计算机专业的,也是半路出家,一起加油学习把!

嗯嗯,共同努力,加个好友
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-19 11:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表