为什么这个多线程python程序从0到99正确打印?
发布时间:2020-12-15 04:20:54 所属栏目:Java 来源:网络整理
导读:这是代码. from Queue import Queuefrom threading import *threadLock = Lock()def do_stuff(q): while True: threadLock.acquire() print q.get() q.task_done() threadLock.release()q = Queue(maxsize=0)num_threads = 10for x in range(100): q.put(x)f
这是代码.
from Queue import Queue from threading import * threadLock = Lock() def do_stuff(q): while True: threadLock.acquire() print q.get() q.task_done() threadLock.release() q = Queue(maxsize=0) num_threads = 10 for x in range(100): q.put(x) for i in range(num_threads): worker = Thread(target=do_stuff,args=(q,)) worker.setDaemon(False) worker.start() q.join() 当我执行此代码时,我得到从0到99打印的数字完美排序.当我删除do_stuff中的锁时,我希望从0到99的数字打印未排序,但即使有一些错误的数字在这里和那里,它主要打印从0到99再次排序的范围.为什么?不应该是未分类的,因为我没有以任何方式同步线程? 解决方法
在从队列中检索下一个数字并打印它之间,您的功能不会执行任何其他操作.
Python在执行每个字节码时持有一个锁(GIL),因此只有字节码之间才能进行线程切换.查看函数(没有锁定)向我们显示,只有一个位置,线程切换会让另一个线程抓住下一个数字并在前一个线程可以打印它们之前打印它: >>> import dis >>> def do_stuff(q): ... while True: ... print q.get() ... q.task_done() ... >>> dis.dis(do_stuff) 2 0 SETUP_LOOP 31 (to 34) >> 3 LOAD_GLOBAL 0 (True) 6 POP_JUMP_IF_FALSE 33 3 9 LOAD_FAST 0 (q) 12 LOAD_ATTR 1 (get) 15 CALL_FUNCTION 0 18 PRINT_ITEM 19 PRINT_NEWLINE 4 20 LOAD_FAST 0 (q) 23 LOAD_ATTR 2 (task_done) 26 CALL_FUNCTION 0 29 POP_TOP 30 JUMP_ABSOLUTE 3 >> 33 POP_BLOCK >> 34 LOAD_CONST 0 (None) 37 RETURN_VALUE 即使线程在那里切换,另一个线程必须在控制切换回之前完成CALL_FUNCTION和PRINT_ITEM字节码,以便您看到按顺序打印的项目. 线程切换必须在CALL_FUNCTION和PRINT_ITEM之间进行.如果您在那里引入了更多说明,则会增加无序打印数字的机会. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |