1

我有一个非常简单的例子,它打印出名称,但问题是,当我按 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()
4

2 回答 2

3

你的主要问题是你没有声明keep_runningas global,所以main只是创建一个同名的局部变量。

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

如果您希望它始终在所有平台上退出,您还需要做两件事:

  1. join您创建的线程。
  2. Lock使用或其他同步机制保护共享全局变量。

keep_running但是,无论如何,这里并不真正需要共享的全局标志。你已经有一个queue. 只需定义一个可以在队列上发布的特殊“关闭”消息,或者使用关闭队列作为关闭的信号。

当我们这样做时,除非您尝试模拟慢速网络或其他东西,否则您time.sleep的代码中不需要这样做。只要打电话self.queue.get(timeout=0.2)。这样,获取每个条目的时间不是总是需要 0.2 秒,而是最多需要0.2 秒,但如果那里已经有东西,则只需 0 秒。

于 2013-04-24T19:16:35.337 回答
1

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

于 2013-04-24T19:27:23.550 回答