Reputation: 6371
Here's the code:
import time
from threading import Thread
import threading
class Test:
#set the max thread number
threadLimiter = threading.BoundedSemaphore(10)
def go(self):
lstRecordThreads = []
for i in range(1, 200):
Test.threadLimiter.acquire()
try:
recordThread = Thread(target=self.recordExec, args=(i,))
recordThread.start()
time.sleep(0.25);
lstRecordThreads.append(recordThread)
finally:
Test.threadLimiter.release()
for rt in lstRecordThreads:
rt.join()
def recordExec(self, number):
print "current number=["+str(number)+"]"
time.sleep(12);
print "done=["+str(number)+"]";
t = Test()
t.go()
But the result is that the thread number is not limited by the number setting in BoundedSemaphore
. Could anyone give me an explanation on this scenario?
Why doesn't the main thread hang up at code Test.threadLimiter.acquire()
when current sub thread number is already 10? Thanks a lot!
Upvotes: 0
Views: 494
Reputation: 9816
As @Tim Peters says, in your main thread, you acquire a semaphore, create a thread, release the semaphore and repeat this procedure 200 times which never decreases the number of semaphores to 0.
If you want to control the number of threads created, in the main thread, you should acquire a semaphore firstly and then create a thread. At the end of the the thread routine, release the semaphore rather than done by the main thread.
Here is the modification:
#!/usr/bin/env python2.7
#coding: utf-8
import threading
import time
class Test:
#set the max thread number
threadLimiter = threading.BoundedSemaphore(10)
def go(self):
lstRecordThreads = []
for i in range(1, 200):
Test.threadLimiter.acquire()
recordThread = threading.Thread(target=self.recordExec, args=(i,))
recordThread.start()
lstRecordThreads.append(recordThread)
for rt in lstRecordThreads:
rt.join()
def recordExec(self, number):
print "current number=["+str(number)+"]"
time.sleep(1)
print "done=["+str(number)+"]"
print('Active thread count: %d' % (threading.active_count(),))
Test.threadLimiter.release()
if __name__ == '__main__':
t = Test()
t.go()
Upvotes: 2
Reputation: 70602
There's no reason to believe the semaphore isn't working. What's unclear is why you think it isn't. Your main loop doesn't wait for anything - it fires off threads as fast as it can, sleeping a quarter of a second between tries. On each iteration it releases the sempahore. So:
acquire sempahore
create a thread
sleep 0.25 seconds
release sempahore
acquire semaphore
create a thread
sleep 0.25 seconds
release sempahore
etc etc etc. In fact, the semaphore count never goes below 9! Every time you acquire it, you release it before you try to acquire it again.
Sorry, but can't guess what you intended to do.
Upvotes: 0