Ожидание завершения потоков с помощью соединения.Довольно простой - PullRequest
3 голосов
/ 26 февраля 2012

У меня довольно простое задание, но у меня проблема с тем, чтобы мой основной поток ожидал завершения всех остальных потоков, которые я создал.

Этот код ничего не делает, он просто предназначен для работы с потоками.

Вот мой код:

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

Ответы [ 2 ]

6 голосов
/ 26 февраля 2012

Вы не можете видеть stderr, потому что вы так много печатаете в stdout, но у вас есть эта ошибка:

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

… что может быть тем, что вы ожидали увидеть, поскольку это происходит после того, как все цифры напечатаны.

3 голосов
/ 26 февраля 2012

Я боролся с этим некоторое время, и я нашел способ, который работает для меня - это набор вещей, которые я нашел в Интернете, и теперь это мой основной «шаблон», когда я работаю с многопоточными приложениями.Он не дает конкретного ответа на ваш вопрос, но показывает способ использования стандартных библиотек на языке 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$ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...