为什么线程数增加了python中的threading.BoundedSemaphore的设置?

时间:2013-12-10 05:48:01

标签: python multithreading

以下是代码:

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

但结果是线程号不受BoundedSemaphore中数字设置的限制。谁可以给我一个关于这种情况的解释?

当前子线程数已经是10时,为什么主线程在代码Test.threadLimiter.acquire()没有挂起?非常感谢!

2 个答案:

答案 0 :(得分:2)

正如@Tim Peters所说,在你的主线程中,你获得一个信号量,创建一个线程,释放信号量并重复这个过程200次,从而不会将信号量减少到0。

如果要控制创建的线程数,请在主线程中首先获取信号量,然后创建一个线程。在线程例程结束时,释放信号量而不是主线程完成。

以下是修改:

#!/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()

答案 1 :(得分:0)

没有理由相信信号量不起作用。目前尚不清楚为什么你认为它不是。你的主循环不会等待任何东西 - 它会尽可能快地触发线程,在尝试之间休眠四分之一秒。在每次迭代时,它会释放sempahore。所以:

acquire sempahore
create a thread
sleep 0.25 seconds
release sempahore

acquire semaphore
create a thread
sleep 0.25 seconds
release sempahore
事实上,信号量计数永远不会低于9!每次获得它时,都会在尝试再次获取之前将其释放。

抱歉,但无法猜出你想要做什么。