1

在下面的示例中,如果您多次执行该程序,它每次都会生成一个具有新 ID 的新线程。1.如何在任务完成时终止所有线程?2. 我如何为线程分配名称/ID?

import threading, Queue 

THREAD_LIMIT = 3                 
jobs = Queue.Queue(5)           # This sets up the queue object to use 5 slots 
singlelock = threading.Lock()   # This is a lock so threads don't print trough each other 

# list  
inputlist_Values = [ (5,5),(10,4),(78,5),(87,2),(65,4),(10,10),(65,2),(88,95),(44,55),(33,3) ] 

def DoWork(inputlist): 
    print "Inputlist received..."
    print inputlist 

    # Spawn the threads 
    print "Spawning the {0} threads.".format(THREAD_LIMIT) 
    for x in xrange(THREAD_LIMIT): 
        print "Thread {0} started.".format(x) 
        # This is the thread class that we instantiate. 
        worker().start() 

    # Put stuff in queue 
    print "Putting stuff in queue"
    for i in inputlist: 
        # Block if queue is full, and wait 5 seconds. After 5s raise Queue Full error. 
        try: 
            jobs.put(i, block=True, timeout=5) 
        except: 
            singlelock.acquire() 
            print "The queue is full !"
            singlelock.release() 

    # Wait for the threads to finish 
    singlelock.acquire()        # Acquire the lock so we can print 
    print "Waiting for threads to finish."
    singlelock.release()        # Release the lock 
    jobs.join()                 # This command waits for all threads to finish. 

class worker(threading.Thread): 
    def run(self): 
        # run forever 
        while 1: 
            # Try and get a job out of the queue 
            try: 
                job = jobs.get(True,1) 
                singlelock.acquire()        # Acquire the lock 
                print self
                print "Multiplication of {0} with {1} gives {2}".format(job[0],job[1],(job[0]*job[1]))         
                singlelock.release()        # Release the lock 
                # Let the queue know the job is finished. 
                jobs.task_done() 
            except: 
                break           # No more jobs in the queue 


def main():    
    DoWork(inputlist_Values)
4

2 回答 2

1

如何在任务完成时终止所有线程?

如果线程看到它,您可以将THREAD_LIMIT标记值(例如,None)放在队列的末尾并退出线程的方法。run()

在您的主线程退出时,所有非守护线程都已加入,因此如果任何线程处于活动状态,程序将继续运行。守护程序线程在您的程序退出时终止。

如何为线程分配名称/ID?

您可以通过将名称传递给构造函数或.name直接更改来分配名称。

线程标识符.ident是一个只读属性,在活动线程中是唯一的。如果一个线程退出而另一个线程启动,它可能会被重用。


multiprocessing.dummy.Pool您可以使用提供相同接口multiprocessing.Pool但使用线程而不是进程的方式重写代码:

#!/usr/bin/env python
import logging
from multiprocessing.dummy import Pool

debug = logging.getLogger(__name__).debug

def work(x_y):
    try:
        x, y = x_y # do some work here
        debug('got %r', x_y)
        return x / y, None
    except Exception as e:
        logging.getLogger(__name__).exception('work%r failed', x_y) 
        return None, e

def main():
    logging.basicConfig(level=logging.DEBUG,
        format="%(levelname)s:%(threadName)s:%(asctime)s %(message)s")

    inputlist = [ (5,5),(10,4),(78,5),(87,2),(65,4),(10,10), (1,0), (0,1) ]
    pool = Pool(3)
    s = 0.
    for result, error in pool.imap_unordered(work, inputlist):
        if error is None:
           s += result
    print("sum=%s" % (s,))
    pool.close()
    pool.join()

if __name__ == "__main__":
   main()

输出

DEBUG:Thread-1:2013-01-14 15:37:37,253 got (5, 5)
DEBUG:Thread-1:2013-01-14 15:37:37,253 got (87, 2)
DEBUG:Thread-1:2013-01-14 15:37:37,253 got (65, 4)
DEBUG:Thread-1:2013-01-14 15:37:37,254 got (10, 10)
DEBUG:Thread-1:2013-01-14 15:37:37,254 got (1, 0)
ERROR:Thread-1:2013-01-14 15:37:37,254 work(1, 0) failed
Traceback (most recent call last):
  File "prog.py", line 11, in work
    return x / y, None
ZeroDivisionError: integer division or modulo by zero
DEBUG:Thread-1:2013-01-14 15:37:37,254 got (0, 1)
DEBUG:Thread-3:2013-01-14 15:37:37,253 got (10, 4)
DEBUG:Thread-2:2013-01-14 15:37:37,253 got (78, 5)
sum=78.0
于 2013-01-11T03:40:45.150 回答
0

除非您告诉它们停止,否则线程不会停止。

我的建议是您将一个stop变量添加到您的Thread子类中,并检查该变量是否True在您的运行循环中(而不是while 1:)。

一个例子:

class worker(threading.Thread): 
    def __init__(self):
         self._stop = False

    def stop(self):
         self._stop = True

    def run(self): 
        # run until stopped 
        while not self._stop:                 
            # do work

然后,当您的程序退出(无论出于何种原因)时,您必须确保stop在所有工作线程上调用该方法。

关于您的第二个问题,是否为您的子类添加name变量对您Thread有用?

于 2013-01-11T00:08:06.800 回答