我有一个非常基本的任务,但我有一个问题让我的主线程等待我生成的所有其他线程完成。
这段代码没有做太多任何事情,它只是作为一个线程练习。
这是我的代码:
import time
from threading import Thread
def printNumbers(lowEnd, highEnd):
while(lowEnd <= highEnd):
print(repr(lowEnd))
lowEnd += 1
countTo = 100000
#Test using 1 thread.
startSingleThread = time.clock()
printNumbers(0,countTo)
elapsedSingleThread = (time.clock() - startSingleThread)
#Test using 10 threads
numberOfThreads = 10
countAmountPerThread = countTo/numberOfThreads
startTenThread = time.clock()
for i in range(numberOfThreads):
threadLowEnd = i*countAmountPerThread
threadHighEnd = (i+1)*countAmountPerThread
t = Thread(target=printNumbers, args=(threadLowEnd,threadHighEnd,))
t.start()
#Join all existing threads to main thread.
for thread in threading.enumerate():
if thread is not threading.currentThread():
thread.join()
elapsedTenThread = (time.clock() - startTenThread)
print("Time for 1 thread: " + repr(elapsedSingleThread))
print("time for 10 threads: " + repr(elapsedTenThread))
答案 0 :(得分:6)
你看不到stderr,因为你打印了很多东西,但是你有这个错误:
Traceback (most recent call last):
File "test.py", line 29, in <module>
for thread in threading.enumerate():
NameError: name 'threading' is not defined
如果我将import threading
添加到顶部,我会收到此输出:
Time for 1 thread: 1.0224820000000001
time for 10 threads: 1.421281
...这可能是你期望看到的,因为它是在打印完所有数字后发生的。
答案 1 :(得分:3)
我已经和它斗争了一段时间,我发现了一种适合我的方式 - 它是我在网上找到的东西的集合,现在它是我使用多线程应用程序时的主要“模式”。它没有具体回答您的问题,但它显示了以Pythonic方式利用标准库的方法。但是,请记住,没有打扰阅读标准的图书馆文档。
from threading import Thread, Lock
from Queue import Queue
from datetime import datetime
import time
import random
class Worker(Thread):
"""This is the main worker - it will process jobs as long as the "job
queue" has jobs available.
"""
# this lock is used to avoid messing up the screen output - only
# one worker will write to screen at a given time. It is
# technically a Mutual Exclusion (mutex)
screen_mutex = Lock()
def __init__(self, queue):
# initialize the base class
super(Worker, self).__init__()
self.queue = queue
def log(self, message):
"""This convenience function is used to print a message to the
screen. You are better off using the logging module, but
beware! It is not thread safe (use a server).
"""
Worker.screen_mutex.acquire()
print("{timestamp:%d-%b-%Y %H:%M:%S.%f UTC} "
"{name}: {message}".format(timestamp=datetime.utcnow(),
name=self.getName(),
message=message))
Worker.screen_mutex.release()
def run(self):
"""This is the method called when you start the thread."""
# The following is an infinite loop which will continue
# processing jobs as long as there are jobs available in the
# queue
while True:
# this is how you get a job from the queue - this call
# will block until a job is available, or when the parent
# thread finishes
job = self.queue.get()
# in this case the job is simply a random number
# indicating how many seconds to sleep (typical example)
self.log("sleeping for {0} seconds".format(job))
time.sleep(job)
self.log("finished sleeping")
# when the job is done, you signal the queue - refer to
# the Queue module documentation
self.queue.task_done()
def main(number_of_jobs=10, number_of_workers=3):
# create the queue where you will put the jobs
queue = Queue()
# create the pool of workers (notice that you pass them the queue
# upon construction).
for _ in range(number_of_workers):
worker = Worker(queue)
# you "daemonize" a thread to ensure that the threads will
# close when the main program finishes
worker.daemon = True
worker.start()
# now it is time to add the jobs to the queue
for _ in range(number_of_jobs):
# a random duration between 2 and 5 seconds
duration = random.randint(2,5)
queue.put(duration)
# now wait for all workers to finish - JOIN THE QUEUE
queue.join()
if __name__ == "__main__":
import sys
if len(sys.argv) == 3:
nj = int(sys.argv[1])
nw = int(sys.argv[2])
else:
nj = 10
nw = 3
# call main
main(nj, nw)
示例输出:
computer$ python example.py
25-Feb-2012 21:21:25.924856 UTC Thread-1: sleeping for 2 seconds
25-Feb-2012 21:21:25.925439 UTC Thread-2: sleeping for 3 seconds
25-Feb-2012 21:21:25.925523 UTC Thread-3: sleeping for 5 seconds
25-Feb-2012 21:21:27.925513 UTC Thread-1: finished sleeping
25-Feb-2012 21:21:27.925696 UTC Thread-1: sleeping for 5 seconds
25-Feb-2012 21:21:28.925561 UTC Thread-2: finished sleeping
25-Feb-2012 21:21:28.925742 UTC Thread-2: sleeping for 5 seconds
25-Feb-2012 21:21:30.925547 UTC Thread-3: finished sleeping
25-Feb-2012 21:21:30.925728 UTC Thread-3: sleeping for 5 seconds
25-Feb-2012 21:21:32.925781 UTC Thread-1: finished sleeping
25-Feb-2012 21:21:32.925963 UTC Thread-1: sleeping for 5 seconds
25-Feb-2012 21:21:33.925822 UTC Thread-2: finished sleeping
25-Feb-2012 21:21:33.926003 UTC Thread-2: sleeping for 2 seconds
25-Feb-2012 21:21:35.925833 UTC Thread-3: finished sleeping
25-Feb-2012 21:21:35.926013 UTC Thread-3: sleeping for 3 seconds
25-Feb-2012 21:21:35.926244 UTC Thread-2: finished sleeping
25-Feb-2012 21:21:35.926420 UTC Thread-2: sleeping for 5 seconds
25-Feb-2012 21:21:37.926035 UTC Thread-1: finished sleeping
25-Feb-2012 21:21:38.926158 UTC Thread-3: finished sleeping
25-Feb-2012 21:21:40.926697 UTC Thread-2: finished sleeping
computer$