Python: Understanding Threading Module

2019-09-19 14:04发布

While learning Python's threading module I've run a simple test. Interesting that the threads are running sequentially and not parallel. Is it possible to modify this test code so a program executes the threads in same fashion as multiprocessing does: in parallel?

import threading

def mySlowFunc(arg):
    print "\nStarting...", arg
    m=0
    for i in range(arg):
        m+=i
    print '\n...Finishing', arg

myList =[35000000, 45000000, 55000000]

for each in myList:
    thread = threading.Thread(target=mySlowFunc, args=(each,) )
    thread.daemon = True
    thread.start()
    thread.join()

print "\n Happy End \n"

REVISED CODE:

This version of the code will initiate 6 'threads' running in 'parallel'. But even while there will be 6 threads only two CPU's threads are actually used (6 other Physical CPU threads will be idling and doing nothing).

import threading

def mySlowFunc(arg):
    print "\nStarting " + str(arg) + "..."
    m=0
    for i in range(arg):
        m+=i
    print '\n...Finishing ' + str(arg)

myList =[35000000, 45000000, 55000000, 25000000, 75000000, 65000000]


for each in myList:
    thread = threading.Thread(target=mySlowFunc, args=(each,) )
    thread.daemon = False
    thread.start()

print "\n Bottom of script reached \n"

2条回答
家丑人穷心不美
2楼-- · 2019-09-19 14:37

If python didn't have the GIL, you ought to be able to see true parallelism by changing your code to only join after you have started all threads:

threads = []
for each in myList:
  t = threading.Thread(target=mySlowFunc, args=(each,) )
  t.daemon = True
  t.start()
  threads.append(t)
for t in threads:
  t.join()

With the above code in python, you should at least be able to see interleaving: thread #2 doing some work before thread #1 has completed. But, you won't see genuine parallelism. See the GIL link for more background.

查看更多
Emotional °昔
3楼-- · 2019-09-19 14:50

From the docs for the join method:

Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception – or until the optional timeout occurs.

Just create a list of threads and join them after launching every single one of them.

Edit:

The threads are executing in parallel, you can think of python's threads like a computer with a single core, the thing is, python's threads are best for IO operations (reading/writing a big file, sending data through a socket, that sort of thing). If you want CPU power you need to use the multiprocessing module

查看更多
登录 后发表回答