找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 5972|回复: 11

[求助] 惊!python现重大bug!

1

主题

7

帖子

7

积分

贫民

积分
7
james 发表于 2018-3-22 17:27:08 | 显示全部楼层 |阅读模式
首先原谅我这个标题党,但是我有一个疑惑一直没有解决,希望大家能帮下我
首先是一段代码
from multiprocessing import Process
import queue


def f():
    q.put([3, None, 'dasda'])
    # print(q.get())


if __name__ == '__main__':
    q = queue.Queue()
    p = Process(target=f,)
    p.start()
    print(q.get())
    p.join()
代码挺简单的,我先说下自己的解释
首先在主进程生成一个线程队列q
开启一个子进程p
然后在子进程中操作主进程中的q,(这是不行的,因为进程间数据不共享,这里大家也都知道)
然后在主进程get

然后这段代码教程中是报错q未定义,我跑了一下是阻塞在q.get()这里了,然后f方法中没有报错,可以put也可以get
因为跟教程中不一样,所以找了一些朋友跑了一下,然后结果也是各有不同,
有的是直接报错q没有定义,有的是阻塞在下面的get为空的时候了
也就是说有的子进程里定义了q,有的子进程没有定义q
这是什么原因啊?有的系统是osx,有的是win,版本都是3.6
我的是osx,阻塞在get的时候了,我有个朋友用的win,也是阻塞了,

这里就产生了不同的意见,有的人觉得f里没有定义q,所以应该报错

但是我也有点疑惑,因为之前学进程了解到子进程中的数据和资源等等是拷贝自父进程的,所以说这里不报错是不是因为子进程中存在一个定义了的
q队列?如果这样解释就合理了,但是不明白为什么有的电脑报错,

如果这里操作的是主进程的q的话,那么这个报错未定义也是合理的,

所以希望大佬能帮我解疑

这个是朋友跑的报错
QQ20180322-0.png


这是我跑的阻塞在get
CEE607D15B8E6C6F6DF973A449452851.jpg

有人能解答么????

回复

使用道具 举报

1

主题

7

帖子

7

积分

贫民

积分
7
james  楼主| 发表于 2018-3-22 17:29:36 | 显示全部楼层
刚才在乌班图 3.5的环境跑了一下 阻塞在get的时候
回复 支持 反对

使用道具 举报

1

主题

7

帖子

7

积分

贫民

积分
7
james  楼主| 发表于 2018-3-22 18:22:44 | 显示全部楼层
进程间数据不共享,但是子进程到底有没有复制父进程定义的队列?我打印了主进程子进程中队列q的内存地址发现一样,这是说明子进程操作了主进程的数据了么?
回复 支持 反对

使用道具 举报

1

主题

7

帖子

7

积分

贫民

积分
7
james  楼主| 发表于 2018-3-22 18:29:38 | 显示全部楼层
后来了解了一下虚拟地址一样不代表值一样
回复 支持 反对

使用道具 举报

0

主题

3

帖子

3

积分

贫民

积分
3
robin-mos 发表于 2018-3-23 09:38:46 | 显示全部楼层
这里的阻塞,是因为队列里面没有数据,调用get的时候会阻塞,你get(block = False) 就不会阻塞,会直接报空队列错误
回复 支持 反对

使用道具 举报

0

主题

3

帖子

3

积分

贫民

积分
3
robin-mos 发表于 2018-3-23 09:41:46 | 显示全部楼层
你id(q) 获取的内存地址都是不一样的。
回复 支持 反对

使用道具 举报

1

主题

7

帖子

7

积分

贫民

积分
7
james  楼主| 发表于 2018-3-23 10:26:04 | 显示全部楼层
robin-mos 发表于 2018-3-23 09:38
这里的阻塞,是因为队列里面没有数据,调用get的时候会阻塞,你get(block = False) 就不会阻塞,会直接报空 ...

这是基本的知识,老哥你再看看我问题的意思,我说的是不同的电脑运行结果不同,阻塞这种基本我当然知道为什么阻塞。。。
回复 支持 反对

使用道具 举报

1

主题

7

帖子

7

积分

贫民

积分
7
james  楼主| 发表于 2018-3-23 10:28:18 | 显示全部楼层
robin-mos 发表于 2018-3-23 09:38
这里的阻塞,是因为队列里面没有数据,调用get的时候会阻塞,你get(block = False) 就不会阻塞,会直接报空 ...

为什么有的电脑跑到q.put直接报错了,有的能跑到get然后阻塞
这就分两种情况,一种是子进程存在定义了的q,一种是子进程不存在定义了的q
为什么在不同的电脑上会出现不同的情况,这是我的问题老哥
回复 支持 反对

使用道具 举报

0

主题

3

帖子

3

积分

贫民

积分
3
robin-mos 发表于 2018-3-23 11:24:51 | 显示全部楼层
james 发表于 2018-3-23 10:28
为什么有的电脑跑到q.put直接报错了,有的能跑到get然后阻塞
这就分两种情况,一种是子进程存在定义了的q ...

我的电脑上面出现的是q未定义
回复 支持 反对

使用道具 举报

1

主题

7

帖子

7

积分

贫民

积分
7
james  楼主| 发表于 2018-3-23 11:59:08 | 显示全部楼层
robin-mos 发表于 2018-3-23 11:24
我的电脑上面出现的是q未定义

很好,你找到了问题所在,那老哥知道什么原因么?系统?库版本?python版本?编译器?我到现在还不清楚什么原因,在我电脑上子进程里的q存在还可以put 和get,我现在猜测是系统原因,但是我现在不知道应该以哪一个为标准,目前是以乌班图为标准
回复 支持 反对

使用道具 举报

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

本版积分规则

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