It seems that IDLE (part of the standard Python Windows install) will not execute multithreaded programs correctly without nasty hangs or bugout crashes. Does anyone know of a way to fix this?
The following program will always hang in IDLE but complete normally when executed with the Python interpreter directly:
import threading, time
printLock = threading.Lock()
def pl(s):
printLock.acquire()
print s
printLock.release()
class myThread( threading.Thread ):
def run(self):
i = 0
for i in range(0,30):
pl(i)
time.sleep(0.1)
t = myThread()
t.start()
while threading.activeCount() > 1:
time.sleep(1)
pl( time.time() )
print "all done!"
sample output:
U:\dev\py\multithreadtest>python mt.py
0
1
2
3
4
5
6
7
8
9
1277935368.84
10
11
12
13
14
15
16
17
18
19
1277935369.84
20
21
22
23
24
25
26
27
28
29
1277935370.84
1277935371.84
all done!
output when using IDLE "Run Module" function always hangs indefinitely at around the time the line reading 23 or 24 shows up on my machine.
Python doesn't support multi-threading because Python on the Cpython interpreter does not support true multi-core execution via multithreading. However, Python does have a threading library. The GIL does not prevent threading.
Python is NOT a single-threaded language. Python processes typically use a single thread because of the GIL. Despite the GIL, libraries that perform computationally heavy tasks like numpy, scipy and pytorch utilise C-based implementations under the hood, allowing the use of multiple cores.
If your program is IO-bound, both multithreading and multiprocessing in Python will work smoothly. However, If the code is CPU-bound and your machine has multiple cores, multiprocessing would be a better choice.
Threading Modules. The threading module is a high-level implementation of multithreading used to deploy an application in Python. To use multithreading, we need to import the threading module in Python Program.
import threading
print(threading.activeCount())
prints 1 when run at the command line, 2 when run from Idle. So your loop
while threading.activeCount() > 1:
time.sleep(1)
pl( time.time() )
will terminate in the console but continue forever in Idle.
To fix the problem in the posted code, add something like
initial_threads = threading.activeCount()
after the import and change the loop header to
while threading.activeCount() > initial_threads:
With this change, the code runs through 30 cycles and stops with 'all done!'. I have added this to my list of console Python versus Idle differences that need to be documented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With