multithreading - Why does this multithreaded python program print from 0 to 99 CORRECTLY? -
this code.
from queue import queue 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 x in range(100): q.put(x) in range(num_threads): worker = thread(target=do_stuff, args=(q,)) worker.setdaemon(false) worker.start() q.join()
when execute code, numbers 0 99 printed sorted. when remove locks in do_stuff, expect numbers 0 99 printed unsorted, erroneour numbers here , there, prints range sorted again 0 99. why that? shouldn't unsorted, since i'm not synchronizing threads in way?
your function doesn't else between retrieving next number queue , printing it.
python holds lock (the gil) while executing each bytecode, between bytecodes can threads switch. looking @ function (without locks) shows there one spot thread switch give thread chance grab next number , print before preceding thread can print theirs:
>>> 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
even if thread switched there, thread must complete both call_function
and print_item
bytecodes before control switched back, see items being printed out of order.
the thread switch have take place between call_function
, print_item
. if introduced more instructions there, you'd increase chances of numbers being printed out of order.
Comments
Post a Comment