如何关闭线程并退出命令行?

时间:2013-04-24 19:10:34

标签: python multithreading

我有一个非常简单的例子,它打印出名称,但问题是,当我按ctrl + C时,程序不会返回到正常的命令行界面:

^CStopping 

我只看到我的光标闪烁,但我无法做任何事情,所以我必须关闭窗口并再次打开它。 我正在运行Ubuntu 12.10。

这是我的代码:

import threading
import random
import time
import Queue
import urllib2
import sys

queue = Queue.Queue()
keep_running = True

class MyThread(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue
        self.names = ['Sophia', 'Irina', 'Tanya', 'Cait', 'Jess']

    def run(self):
        while keep_running:
            time.sleep(0.25)
            line = self.names[random.randint(0,len(self.names)-1)]
            queue.put(line)
            self.queue.task_done()

class Starter():
    def __init__(self):
        self.queue = queue
        t = MyThread(self.queue)
        t.start()
        self.next()

    def next(self):
        while True:
            time.sleep(0.2)
            if not self.queue.empty():
                line = self.queue.get()
                print line, self.queue.qsize()
            else:
                print 'waiting for queue'

def main():  
    try:
        Starter()     
        queue.join()
    except KeyboardInterrupt, e:
        print 'Stopping'
        keep_running = False
        sys.exit(1)

main()

2 个答案:

答案 0 :(得分:3)

您的主要问题是您没有将keep_running声明为global,因此main只是创建一个同名的本地变量。

如果你解决了这个问题,它通常会在某些平台上退出。

如果您希望始终退出所有平台,则需要再做两件事:

  1. join您创建的主题。
  2. 使用Lock或其他同步机制保护共享的全局变量。
  3. 但是,无论如何都不需要共享的全局keep_running标志。你已经有了queue。只需定义一个可以在队列中发布的特殊“关闭”消息,或者使用关闭队列作为关闭信号。

    虽然我们处于此状态,但除非您尝试模拟慢速网络或其他内容,否则代码中不需要time.sleep。只需致电self.queue.get(timeout=0.2)即可。这样,而不是总是花费0.2秒来获得每个条目,它将最多 0.2秒,但如果已经存在某些东西,则只需0秒。

答案 1 :(得分:1)

您的主要帖子卡在Starter.next中。然后在那里调用中断并传播到try语句的第一行并被捕获,在调用join之前跳转到except子句。尝试将join调用放入finally块(使用sys.exit)或将其移动到异常处理程序