Why does this multithreaded Python program print correctly from 0 to 99?

This is the code

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()

When I execute this code, I get a perfect order of numbers printed from 0 to 99 When I delete do_ When locking in stuff, I want the numbers from 0 to 99 to print unsorted, but even if there are some wrong numbers here and there, it mainly prints the range of reordering from 0 to 99 Why? Shouldn't it be unclassified because I don't synchronize threads in any way?

Solution

Your function does nothing else between retrieving the next number from the queue and printing it

Python holds a lock (GIL) when executing each bytecode, so thread switching can only be performed between bytecodes The viewing function (no lock) shows us that there is only one position. Thread switching will make another thread grasp the next number and print it before the previous thread can print them:

>>> 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 the thread switches there, another thread must complete the call before the control switches back_ Function and print_ Item bytecode so that you can see the items printed in order

Thread switching must be in call_ Function and print_ Between items If you introduce more instructions there, you will increase the chance of printing numbers out of order

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>