- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直在尝试使用 concurrent.futures.ProcessPoolExecutor
并行化一些代码,但一直有奇怪的死锁,而这不会发生在 ThreadPoolExecutor
中。一个最小的例子:
from concurrent import futures
def test():
pass
with futures.ProcessPoolExecutor(4) as executor:
for i in range(100):
print('submitting {}'.format(i))
executor.submit(test)
在 python 3.2.2(在 64 位 Ubuntu 上)中,这似乎在提交所有作业后一直挂起 - 并且只要提交的作业数量大于工作人员数量,就会发生这种情况。如果我将 ProcessPoolExecutor
替换为 ThreadPoolExecutor
,它将完美运行。
作为调查的尝试,我给每个 future 一个回调来打印 i
的值:
from concurrent import futures
def test():
pass
with futures.ProcessPoolExecutor(4) as executor:
for i in range(100):
print('submitting {}'.format(i))
future = executor.submit(test)
def callback(f):
print('callback {}'.format(i))
future.add_done_callback(callback)
这让我更加困惑 - callback
打印出的 i
的值是它被调用时的值,而不是它被定义时的值(所以我从来没有看到 callback 0
但我得到了很多 callback 99
)。 ThreadPoolExecutor
再次打印出预期值。
想知道这是否是一个错误,我尝试了 python 的最新开发版本。现在,代码至少似乎终止了,但我仍然打印出错误的 i
值。
谁能解释一下:
ProcessPoolExecutor
在 python 3.2 和显然修复了这个死锁的当前开发版本之间发生了什么
为什么正在打印 i
的“错误”值
编辑:正如 jukiewicz 在下面指出的那样,当然打印 i
将在调用回调时打印值,我不知道我在想什么......如果我通过将 i
的值作为其属性之一的可调用对象,按预期工作。
编辑:更多信息:所有回调都已执行,因此看起来是 executor.shutdown
(由 executor.__exit__
调用)无法判断流程是否已完成。这似乎在当前的python 3.3中已完全修复,但是multiprocessing
和concurrent.futures
似乎有很多变化,所以我不知道是什么解决了这个问题。由于我不能使用 3.3(它似乎与 numpy 的发行版或开发版都不兼容),我尝试简单地将其多处理和并发包复制到我的 3.2 安装中,这似乎工作正常。尽管如此,这似乎有点奇怪 - 据我所知 - ProcessPoolExecutor
在最新版本中完全损坏但没有其他人受到影响。
最佳答案
我修改了如下代码,解决了这两个问题。 callback
函数被定义为闭包,因此每次都会使用 i
的更新值。至于死锁,这很可能是在所有任务完成之前关闭 Executor 的原因。等待 future 完成也可以解决这个问题。
from concurrent import futures
def test(i):
return i
def callback(f):
print('callback {}'.format(f.result()))
with futures.ProcessPoolExecutor(4) as executor:
fs = []
for i in range(100):
print('submitting {}'.format(i))
future = executor.submit(test, i)
future.add_done_callback(callback)
fs.append(future)
for _ in futures.as_completed(fs): pass
更新:哦,抱歉,我还没有阅读您的更新,这似乎已经解决了。
关于python - concurrent.futures 代码中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9214214/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!