2013-08-30 48 views
0

我跟踪的线程数量通过旗语这样:如何运行(执行后)在一个线程自动释放一个信号?

#!/usr/bin/python3 
import threading 

class MyThread(threading.Thread): 

    max_threads   = 5 
    max_threads_semaphore = threading.BoundedSemaphore(value=max_threads) 
    semaphore_timeout  = 60 

    def __init__(self, target=None, name=None, args=(), kwargs={}): 
     super().__init__(target=target, name=name, args=args, kwargs=kwargs) 

    def start(self): 
     semaphore_aquired = self.max_threads_semaphore.acquire(blocking=True, timeout=self.semaphore_timeout) 
     if semaphore_aquired: 
      print("Sempahore acquired by:", self.name) 
      super().start() 
     else: 
      raise OSError("Time out aquiring max threads semaphore to start new thread") 

    def join(self): 
     super().join() 
     semaphore_released = self.max_threads_semaphore.release() 

这项工作,但不是我想要的方式。我希望能够到:

def print_test(num): 
    print("executing:", num) 
    sleep(10) 
    print("end of execution:", num) 

threads_dict = dict() 
thread_range = range(1,20) 
for i in thread_range: 
    threads_dict[i] = MyThread(target=print_test(i)) 
    threads_dict[i].start() 
for i in thread_range: 
    threads_dict[i].join() 
    print("joined:", threads_dict[i].name) 

显然,一旦5个线程启动(max_threads),脚本在僵局直到达到信号超时。

我认为start()方法将启动run()方法在一个新的线程。从the manual

start()方法 必须叫每个线程对象最多一次。它安排 用于 控制的一个单独的线程将被调用的对象的run()方法。

所以在MyThread我更换了join()部分具有:

def run(self): 
    super().run() 
    semaphore_released = self.max_threads_semaphore.release() 
    print("Sempahore released by:", self.name) 

但这种代码是不是一个新的线程中执行。输出是:

executing: 1 
end of execution: 1 
Sempahore acquired by: Thread-1 
Sempahore released by: Thread-1 
executing: 2 
end of execution: 2 
Sempahore acquired by: Thread-2 
Sempahore released by: Thread-2 
executing: 3 
end of execution: 3 
Sempahore acquired by: Thread-3 
Sempahore released by: Thread-3 
executing: 4 
end of execution: 4 
Sempahore acquired by: Thread-4 
Sempahore released by: Thread-4 
executing: 5 
end of execution: 5 
Sempahore acquired by: Thread-5 
Sempahore released by: Thread-5 
executing: 6 
end of execution: 6 
Sempahore acquired by: Thread-6 
executing: 7 
Sempahore released by: Thread-6 
end of execution: 7 
Sempahore acquired by: Thread-7 
executing: 8 
Sempahore released by: Thread-7 
end of execution: 8 
Sempahore acquired by: Thread-8 
executing: 9 
Sempahore released by: Thread-8 
end of execution: 9 
Sempahore acquired by: Thread-9 
joined: Thread-1 
joined: Thread-2 
joined: Thread-3 
joined: Thread-4 
joined: Thread-5 
joined: Thread-6 
joined: Thread-7 
joined: Thread-8 
Sempahore released by: Thread-9 
joined: Thread-9 

有没有一种方法,以便在目标函数结束时自动释放信号量重载一个threading.Thread功能?

我不明白为什么输出不是:

Sempahore acquired by: Thread-1 
executing: 1 
Sempahore acquired by: Thread-2 
executing: 2 
Sempahore acquired by: Thread-3 
executing: 3 
Sempahore acquired by: Thread-4 
executing: 4 
Sempahore acquired by: Thread-5 
executing: 5 
(sleep 10 secondes) 
end of execution: 1 
Sempahore released by: Thread-1 
Sempahore acquired by: Thread-6 
executing: 6 
etc.. 

回答

1

至于有关“奇怪”的输出问题。

threads_dict[i] = MyThread(target=print_test(i)) 

这是执行的print_test(I)功能:这是因为你创建新线程之前调用主线程print_test(I)是果然。而作为结果,您过去目标print_test(I)函数执行的结果。

尝试解决此:

threads_dict[i] = MyThread(target=print_test, args=[i,]) 

这种修正后,我有喜欢的输出:

('Sempahore acquired by:', 'Thread-1') 
('Sempahore acquired by:', 'Thread-2') 
('executing:', 1) 
('Sempahore acquired by:', 'Thread-3') 
('executing:', 2) 
('Sempahore acquired by:', 'Thread-4') 
('executing:', 3) 
('Sempahore acquired by:', 'Thread-5') 
('executing:', 4) 
('executing:', 5) 
('end of execution:', 1) 
('Sempahore released by:', 'Thread-1') 
('Sempahore acquired by:', 'Thread-6') 
... 
+0

这是伟大的,它的工作原理现在正是我想要的。谢谢:D –

相关问题