为什么Python';s GIL执行严格的处理顺序?
使用python3运行:为什么Python';s GIL执行严格的处理顺序?,python,multithreading,python-3.x,python-multithreading,gil,Python,Multithreading,Python 3.x,Python Multithreading,Gil,使用python3运行: from concurrent.futures import ThreadPoolExecutor, as_completed def main(): with ThreadPoolExecutor(max_workers=16) as producersPool: for i in [1,2,3,4,5,6,7,8,9,0]: producersPool.submit((lambda i : print(i))(i))
from concurrent.futures import ThreadPoolExecutor, as_completed
def main():
with ThreadPoolExecutor(max_workers=16) as producersPool:
for i in [1,2,3,4,5,6,7,8,9,0]:
producersPool.submit((lambda i : print(i))(i))
if __name__ == "__main__":
main()
总是一样的
现在我希望你能正确地理解我的意思——我不一定希望这些任务被重新排序,但我只是想知道为什么会发生排序?我的意思是,人们可以期望在一个线程内以确定性的方式完成任务,但是线程的严格排队对我来说似乎有点奇怪
无论如何,如何在Python3中获得真正的并发性?(据我所知,Jython和IronPython只支持2.x)。所有作业都是在提交之前执行的,它们中没有一个只会写入输出流。您提交调用每个lambda
的结果
即使您使用:
1
2
3
4
5
6
7
8
9
0
每个线程中没有足够的内容可被另一个线程抢占,因此它们都在任何其他线程进入之前完成。所有作业在提交之前都会执行,并且它们都只会写入输出流。您提交调用每个lambda
的结果
即使您使用:
1
2
3
4
5
6
7
8
9
0
每个线程中没有足够的线程可被另一个线程抢占,因此它们都在其他线程进入之前完成。回答问题的第二部分: “如何在Python 3中获得真正的并发性?” 您可以使用以下模块: “多处理是一个包,它支持使用 与线程模块类似的API。多处理程序包 同时提供本地和远程并发性,有效地进行侧步 全局解释器通过使用子进程而不是线程来锁定。“
由于您的示例使用了
concurrent.futures
中的ThreadPoolExecutor
,请查看同一软件包中的内容。它类似于ThreadPoolExecutor
,但使用进程(而不是线程),因此不会受到GIL的阻碍。回答问题的第二部分:
“如何在Python 3中获得真正的并发性?”
您可以使用以下模块:
“多处理是一个包,它支持使用
与线程模块类似的API。多处理程序包
同时提供本地和远程并发性,有效地进行侧步
全局解释器通过使用子进程而不是线程来锁定。“
由于您的示例使用了
concurrent.futures
中的ThreadPoolExecutor
,请查看同一软件包中的内容。它类似于ThreadPoolExecutor
,但使用进程(而不是线程),因此它不会受到GIL的阻碍。啊,我明白了。好吧,我添加了sleep(5)
,现在它似乎以一种真正随机的方式打印列表。谢谢。示例中的实际问题是打印发生在主线程中,OP只向线程池提交None
。请参阅我对@l4mpi的评论(lambdas在这里看起来有点邋遢,所以我创建了一个函数)。啊,我明白了。好吧,我添加了sleep(5)
,现在它似乎以一种真正随机的方式打印列表。谢谢。示例中的实际问题是打印发生在主线程中,OP从不向线程池提交除None
之外的任何内容……请参阅我对@l4mpi的评论(lambdas在这里看起来有点邋遢,所以我创建了一个函数)。您的示例包含一个重要错误:您实际上正在调用lambda,并且只将结果(始终为无)传递给submit
。观察到的行为与线程池无关。你可能想写(lambda i:(lambda:print(i)))(i)
。@l4mpi,是的,我已经注意到了,并且已经击中了自己的脸。我将代码编辑为producersPool.submit(sleepy,I)
,它按预期运行,即是一种相当不可预测的方式。谢谢。您的示例包含一个重要错误:您实际上正在调用lambda,并且只将结果(始终为无)传递给submit
。观察到的行为与线程池无关。你可能想写(lambda i:(lambda:print(i)))(i)
。@l4mpi,是的,我已经注意到了,并且已经击中了自己的脸。我将代码编辑为producersPool.submit(sleepy,I)
,它按预期运行,即是一种相当不可预测的方式。谢谢。是的,我看到了,但是我没有考虑到可能性。太好了,很抱歉我不能一次接受两个答案(我不应该一次问两个:))是的,我看到了,但只是没有考虑到可能性。太好了,很抱歉我不能同时接受两个答案(我不应该一次问两个:)