【问题标题】:How to stop a python 2.7 program that has blocking calls in some threads如何停止在某些线程中有阻塞调用的python 2.7程序
【发布时间】:2018-01-28 05:04:07
【问题描述】:

我有一个 Python 程序,它有一些执行阻塞调用的线程。 例如:

#!/usr/bin/python
import threading, tty, sys, os, signal

# super-awesome thread launcher (re-inventing the wheel because I'm
# too lazy to research what they called this)
class Launch(threading.Thread):
    def __init__(self, f):
        threading.Thread.__init__(self)
        self.f    = f
        self.start()
    def run(self):
        self.f()

# structure to hold unprocessed chars
Term_Lock    = threading.Lock()
Term_Cond    = threading.Condition(Term_Lock)
Term_In      = []

# launch a thread to retrieve characters from the terminal
tty.setraw(sys.stdin.fileno())
@Launch
def Stdin_Reader():
    while True:
        c = sys.stdin.read(1)
        with Term_Lock:
            Term_In.append(c)
            Term_Cond.notify()

# main thread
c = None
with Term_Lock:        
    Term_Cond.wait(1)
    if Term_In:
        c = Term_In.pop(0)
if c:
    print "You pressed '%s'\r" % c
else:
    print "You were too slow!\r"

# Lord have mercy on my soul
os.kill(os.getpid(), signal.SIGKILL)

虽然这个程序运行得很好,但最后的os.kill() 有点令人不安。我用许多其他语言编程过,以前从未见过这种问题。我对语言发明者删除应该在主线程末尾发生的 _Exit 调用没有问题。但是接下来要从系统 API 中完全隐藏 _Exit,这很神经。

确实,我们看到的是关于如何以合理的方式停止程序的基本问题。例如:

Exit a process while threads are sleeping

他们说使用 Python 3.0 守护线程。当 Python 3.0 最终引入通用的 2.7 兼容性时,我会记住这一点。所以下一个最好的办法是停止所有线程:

Is there any way to kill a Thread in Python?

但投票最多的回答基本上是“不要那样做”。好的。所以以我上面的例子为例。阻止对sys.stdin.read() 的呼叫。我们如何解决这个问题?他们说使用select()

Read file with timeout in Python

尽管如此。 Select 仅适用于文件描述符和超时。如果我想从不使用文件描述符生成数据的程序和/或库中接收其他输入怎么办?所以我必须创建内存管道或其他东西?这很快就变得荒谬了。

那么,我是否只需要继续使用os.kill() 直到 Python 3.0 被接受?

或者有没有更好的方法?

【问题讨论】:

  • 如果您决定使用文件描述符、管道、select() 等,您可能有兴趣查看 ZeroMQ。如果要使用 Actor 模型,zmq 可以提供很大帮助。

标签: python multithreading python-2.7 exit sys


【解决方案1】:

我认为os._exit(0)是我想要的:

What is difference between sys.exit(0) and os._exit(0)

它似乎工作得很好。我什至可以把它放在我自己的 Exit() 函数中,它可以做任何我想做的清理工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    相关资源
    最近更新 更多