- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们知道multiprocessing.Pool
必须在函数定义之后初始化才能在其上运行。但是我发现下面的代码对我来说是难以理解的
import os
from multiprocessing import Pool
def func(i): print('first')
pool1 = Pool(2)
pool1.map(func, range(2)) #map-1
def func(i): print('second')
func2 = func
print('------')
pool1.map(func, range(2)) #map-2
pool1.map(func2, range(2)) #map-3
pool2 = Pool(2)
print('------')
pool2.map(func, range(2)) #map-4
pool2.map(func2, range(2)) #map-5
first #map-1
first
------
first #map-2
first
first #map-3
first
------
second #map-4
second
second #map-5
second
map-2
按预期打印。
'first'
是在
map-3
第一次出现之前初始化的。因此
func2
确实被执行,而
pool1
则不是。为什么?
def func2(i): print('second')
func2
就找不到许多帖子中提到的名字
func2 = func
,比如
this one。两个案子有什么区别?
最佳答案
tl;dr:map-3
中调用第一个func
的问题,当您希望第二个func
时,是因为Pool.map()
使用pickle序列化func.__name__
,pickle解析为func
,即使它被分配给func2
引用,并被发送到子进程,子进程在本地向子进程查找func
。
好的,我可以数一数下面列出的四个不同的问题,我认为您已经被告知了名称空间和分叉过程,直接进入您的问题的乐趣☺
①但是map-3如何找到func2这个名字呢?
②所以func2=func确实执行,而def func(i):print('second')不执行。为什么?
③那么map-3就找不到很多帖子提到的func2这个名字,比如这个。两个案子有什么区别?
④据我所知,参数通过pickling传递给从进程,但是pool如何将被调用的函数传递给其他进程?或者子进程如何找到被调用的函数?
所以我添加了更多的代码来展示更多的内部特性:
import os
from multiprocessing import Pool
print(os.getpid(), 'parent')
def func(i):
print(os.getpid(), 'first', end=" | ")
if 'func' in globals():
print(globals()['func'], end=" | ")
else:
print("no func in globals", end=" | ")
if 'func2' in globals():
print(globals()['func2'])
else:
print("no func2 in globals")
print('------ map-1')
pool1 = Pool(2)
pool1.map(func, range(2)) #map-1
def func(i):
print(os.getpid(), 'second', end=" | ")
if 'func' in globals():
print(globals()['func'], end=" | ")
else:
print("no func in globals", end=" | ")
if 'func2' in globals():
print(globals()['func2'])
else:
print("no func2 in globals")
func2 = func
print('------ map-2')
pool1.map(func, range(2)) #map-2
print('------ map-3')
pool1.map(func2, range(2)) #map-3
pool2 = Pool(2)
print('------ map-4')
pool2.map(func, range(2)) #map-4
print('------ map-5')
pool2.map(func2, range(2)) #map-5
21512 parent
------ map-1
21513 first | <function func at 0x7f62d67f7cf8> | no func2 in globals
21514 first | <function func at 0x7f62d67f7cf8> | no func2 in globals
------ map-2
21513 first | <function func at 0x7f62d67f7cf8> | no func2 in globals
21514 first | <function func at 0x7f62d67f7cf8> | no func2 in globals
------ map-3
21513 first | <function func at 0x7f62d67f7cf8> | no func2 in globals
21514 first | <function func at 0x7f62d67f7cf8> | no func2 in globals
------ map-4
21518 second | <function func at 0x7f62d531bed8> | <function func at 0x7f62d531bed8>
21519 second | <function func at 0x7f62d531bed8> | <function func at 0x7f62d531bed8>
------ map-5
21518 second | <function func at 0x7f62d531bed8> | <function func at 0x7f62d531bed8>
21519 second | <function func at 0x7f62d531bed8> | <function func at 0x7f62d531bed8>
pool1
从来没有一个
func2
被添加到名称空间中。所以肯定有一些可疑的事情发生了,对于我来说,现在彻底研究
multiprocessing
的源代码和调试器来理解发生了什么已经太迟了。
pickle
模块发现不知何故,
func2
解决了
0x7f62d531bed8
,因此它把已知的“标签”
func
。即。:
func2 → 0x7f62d531bed8 → func → [PICKLE] → globals()['func'] → 0x7f62d67f7cf8
func
重命名为
0x7f62d67f7cf8
,下面是我得到的:
------ map-3
Process PoolWorker-1:
Process PoolWorker-2:
Traceback (most recent call last):
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
self._target(*self._args, **self._kwargs)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker
File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker
task = get()
task = get()
File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get
File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get
return recv()
return recv()
AttributeError: 'module' object has no attribute 'func2'
AttributeError: 'module' object has no attribute 'func2'
func()
更改为
func2()
------ map-2
Process PoolWorker-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
Process PoolWorker-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
self._target(*self._args, **self._kwargs)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker
File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker
task = get()
task = get()
File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get
File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get
return recv()
return recv()
AttributeError: 'module' object has no attribute 'func2'
AttributeError: 'module' object has no attribute 'func2'
func = func2
第114行中添加了一个print语句:
job, i, func, args, kwds = task
print("XXX", os.getpid(), job, i, func, args, kwds)
func2 = func
被解析为
pool.py
,它与父函数中的地址相同:
23432 parent
------ map-1
('XXX', 23433, 0, 0, <function mapstar at 0x7f2d02363230>, ((<function func at 0x7f2d0238fcf8>, (0,)),), {})
23433 first | <function func at 0x7f2d0238fcf8> | no func2 in globals
('XXX', 23434, 0, 1, <function mapstar at 0x7f2d02363230>, ((<function func at 0x7f2d0238fcf8>, (1,)),), {})
23434 first | <function func at 0x7f2d0238fcf8> | no func2 in globals
------ map-2
('XXX', 23433, 1, 0, <function mapstar at 0x7f2d02363230>, ((<function func at 0x7f2d0238fcf8>, (0,)),), {})
23433 first | <function func at 0x7f2d0238fcf8> | no func2 in globals
('XXX', 23434, 1, 1, <function mapstar at 0x7f2d02363230>, ((<function func at 0x7f2d0238fcf8>, (1,)),), {})
23434 first | <function func at 0x7f2d0238fcf8> | no func2 in globals
------ map-3
('XXX', 23433, 2, 0, <function mapstar at 0x7f2d02363230>, ((<function func at 0x7f2d0238fcf8>, (0,)),), {})
23433 first | <function func at 0x7f2d0238fcf8> | no func2 in globals
('XXX', 23434, 2, 1, <function mapstar at 0x7f2d02363230>, ((<function func at 0x7f2d0238fcf8>, (1,)),), {})
23434 first | <function func at 0x7f2d0238fcf8> | no func2 in globals
------ map-4
('XXX', 23438, 3, 0, <function mapstar at 0x7f2d02363230>, ((<function func at 0x1092e60>, (0,)),), {})
23438 second | <function func at 0x1092e60> | <function func at 0x1092e60>
('XXX', 23439, 3, 1, <function mapstar at 0x7f2d02363230>, ((<function func at 0x1092e60>, (1,)),), {})
23439 second | <function func at 0x1092e60> | <function func at 0x1092e60>
------ map-5
('XXX', 23438, 4, 0, <function mapstar at 0x7f2d02363230>, ((<function func at 0x1092e60>, (0,)),), {})
('XXX', 23439, 4, 1, <function mapstar at 0x7f2d02363230>, ((<function func at 0x1092e60>, (1,)),), {})
23438 second | <function func at 0x1092e60> | <function func at 0x1092e60>
23439 second | <function func at 0x1092e60> | <function func at 0x1092e60>
>>> print(func)
<function func at 0x7fc6174e3ed8>
func
:
>>> print("func.__name__:", func.__name__)
func.__name__: func
>>> print("func2.__name__:", func2.__name__)
func2.__name__: func
0x7f2d0238fcf8
阶段将
func.__name__
给
func
时会得到旧的
func2
函数。
pool1
没有找到名称
map-3
,它在
map-3
所指的函数中找到了名称
func2
。所以,这也回答了②和③,因为找到的
func
正在执行原来的
func2
函数。其机制是,使用
func
来pickle和解析两个进程之间的函数名,回答④。
func
中,它使用
if name is None: name = getattr(obj, '__qualname__', None)
if name is None: name = obj.__name__.
func.__name__
,则将使用
pickle._Pickler.save_global
。
if obj2 is not obj: raise PicklingError(...)
__qualname__
。
__name__
是否与父进程的
obj2, parent = _getattribute(module, name)
在内存中相同。
import os
from multiprocessing import Pool
print(os.getpid(), 'parent')
def func(i):
print(os.getpid(), 'first', end=" | ")
if 'func' in globals():
print(globals()['func'], end=" | ")
else:
print("no func in globals", end=" | ")
if 'func2' in globals():
print(globals()['func2'])
else:
print("no func2 in globals")
print('------ map-1')
pool1 = Pool(2)
pool1.map(func, range(2)) #map-1
def func2(i):
print(os.getpid(), 'second', end=" | ")
if 'func' in globals():
print(globals()['func'], end=" | ")
else:
print("no func in globals", end=" | ")
if 'func2' in globals():
print(globals()['func2'])
else:
print("no func2 in globals")
func2.__qualname__ = func.__qualname__
func = func2
print('------ map-2')
pool1.map(func, range(2)) #map-2
print('------ map-3')
pool1.map(func2, range(2)) #map-3
pool2 = Pool(2)
print('------ map-4')
pool2.map(func, range(2)) #map-4
print('------ map-5')
pool2.map(func2, range(2)) #map-5
38130 parent
------ map-1
38131 first | <function func at 0x101856f28> | no func2 in globals
38132 first | <function func at 0x101856f28> | no func2 in globals
------ map-2
38131 first | <function func at 0x101856f28> | no func2 in globals
38132 first | <function func at 0x101856f28> | no func2 in globals
------ map-3
38131 first | <function func at 0x101856f28> | no func2 in globals
38132 first | <function func at 0x101856f28> | no func2 in globals
------ map-4
38133 second | <function func at 0x10339b510> | <function func at 0x10339b510>
38134 second | <function func at 0x10339b510> | <function func at 0x10339b510>
------ map-5
38133 second | <function func at 0x10339b510> | <function func at 0x10339b510>
38134 second | <function func at 0x10339b510> | <function func at 0x10339b510>
func()
定义之后的
func()
是关键,因为pickle将检查
func = func2
(名为
func2
)是否与
func2
相同。如果没有,那么酸洗将失败。
关于python - 创建时与命名空间的Python多处理池交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35886272/
在 python 交互中,有没有办法在每次输入命令后自动从 python 文件执行方法? 例如:如果我有一个打印文件信息的方法,但我不想不断调用该方法,我怎样才能让它在 python 交互中的每个命令
当你使用Edge等浏览器或系统软件播放媒体时,Windows控制中心就会出现相应的媒体信息以及控制播放的功能,如图。 SMTC (SystemMedia
我在主菜单上使用标准的剪切,复制,粘贴操作。它们具有快捷键Ctrl-X,Ctrl-C和Ctrl-V。 当我打开模态表单时FindFilesForm.ShowModal,然后所有快捷方式都可以从表单中使
这是我想要实现的目标:打开一个 shell(korn 或 bash,没关系),从那个 shell,我想打开一个 ssh 连接(ssh user@host)。在某些时候,可能会提示我输入密码,或者可能会
我正在测试在C / C++程序中嵌入Python,但是我缺乏理解。 测试程序很简单: 初始化解释器; 从启动Timer的文件中执行python脚本(每0.1秒增加一个变量); 等待5秒(C++); 从
我正在尝试用java创建Excel文件。现在,我正在使用 Apache POI 库创建文件并将其保存到本地驱动器。有没有办法启动 Excel 并填充数据而不将其保存到硬盘驱动器? 最佳答案 考虑 Do
我有一个黑盒函数,它接受大约 10 个整数输入。该函数返回一个 pandas 数据框,我想捕获输出窗口(通过使用 bbwidget.children)并显示在布局中的其他地方。到目前为止,交互/交互似
我正在体验新的 QQuickWidget。我如何在 QQuickWidget 和 C++ 之间进行交互? C++ QQuickWidget *view = new QQuickWidget(); vi
我正在尝试设置一个使用 TWAIN 的 C# 应用程序 example from code project 除了我需要将 Form 转换为 IMessageFilter 和调用 IMessageFil
我想在使用 redis 的 python 中编写应用程序。我用谷歌搜索,但找不到我的问题的任何结果。通常,我这样做: import redis rs = redis.Redis('localhost'
最近做一个小项目,网页中嵌入google maps,输入经纬度坐标可以定位地图位置并加注标记,点击标记获取远端摄像头数据并在视频窗口实现播放。在实际操作过程中,由于经纬度数据和视频登录的用户名密码数
我需要在这里澄清一些事情: 我有一个网站,每次在浏览器中重新加载网站时都会更新两个变量的值。这个页面显然是一个 HTML 页面,但变量是由 javascript 函数更新的。此页面在我的服务器上运行。
我注意到,auto忽略双条件。这是一个简化的示例: Parameter A B : Prop. Parameter A_iff_B : A B. Theorem foo1: A -> B. Proo
使用 interactive使用多个小部件相当简单,例如: interactive(foo, w1=widget1, w2=widget2, ...) 但是,我想使用 VBox 和 HBox 的组合以
我们提供类似于 imagemagick 的浏览器页面 JavaScript,可帮助人们将图像转换为不同大小和格式。但是,它需要网页交互。 是否可以让人们自动进行这种交互——无需将图像发送到我们的服务器
大家好,我正在尝试制作一个具有大量动画和效果的交互式 UI。 但我不知道是否: 核心图形可以支持用户交互(触摸、拖动等) 核心图形支持对象旋转 核心图形可以以任何方式与 UIKit 和核心动画交互 谢
这是获取维基百科上一篇关于高盛的文章的介绍的链接。 http://en.wikipedia.org/w/api.php?action=query&prop=extracts&titles=Goldma
我正在尝试编写一个 AppleScript 来查询 iCal 并在任何日历中查找给定日期的所有事件。 我首先编写了一个简单的脚本,它对给定日历中的每个事件执行一些简单的操作: tell applica
我在我的 hudson 服务器上使用 jira 插件。将代码提交到 svn 时,我的提交注释包含在我的 jira 问题中,但有什么办法可以将注释归因于执行提交的实际人员,而不是让一个全局 jira 用
我正在播放一段视频来装饰我的用户界面。我隐藏了 AV 播放器控件,但用户仍然可以控制视频。例如,他们可以使用滑动手势快进或快退。 这让我特别惊讶,因为 AVPlayerView 上面有一个覆盖 Vie
我是一名优秀的程序员,十分优秀!