与使用os.system Python的线程()调用。 主线程做对CTRL + C不会退出(Py

2019-08-06 02:05发布

请不要认为这是阅读之前的副本,有很多有关问题, multithreadingkeyboard interrupt ,但我没有发现任何考虑使用os.system,它看起来就像是很重要的。

我有一个python脚本,这使得在工作线程一些外部呼叫。 我希望它退出,如果我按ctrl+c ,但它看起来像主线程忽略它。

事情是这样的:

from threading import Thread
import sys
import os

def run(i):
    while True:
        os.system("sleep 10")
        print i

def main():
    threads=[]
    try:
        for i in range(0, 3):
            threads.append(Thread(target=run, args=(i,)))
            threads[i].daemon=True
            threads[i].start()
        for i in range(0, 3):
            while True:
                threads[i].join(10)
                if not threads[i].isAlive():
                    break

    except(KeyboardInterrupt, SystemExit):
        sys.exit("Interrupted by ctrl+c\n")


if __name__ == '__main__': 
    main() 

出人意料的是,如果我改变它工作正常os.system("sleep 10")time.sleep(10)

Answer 1:

我不知道什么样的操作系统和shell所使用。 我描述了Mac OS X和Linux中的zsh(庆典/ SH应该采取行动相似)。

当你按下Ctrl + C,在你当前终端前台运行的所有程序接收到信号SIGINT 。 你的情况是你的主要的Python程序,并通过使用os.system产生的所有进程。

通过使用os.system子进程然后终止其执行。 通常,当python脚本收到SIGINT,它会引发KeyboardInterrupt异常,但你的主进程忽略,因为SIGINT, os.system() Python的os.system() 调用标准C函数 system()这使得调用进程忽略SIGINT( 男人的Linux / 人的Mac OS X )。

所以,无论你的Python的线程接收SIGINT,这只是孩子的过程谁得到它。

当您删除使用os.system()调用,你的Python程序停止忽略SIGINT,你会得到KeyboardInterrupt

您可以替换os.system("sleep 10")subprocess.call(["sleep", "10"]) subprocess.call()不会使你的过程忽略SIGINT。



Answer 2:

我有这个同样的问题,更多的时间比我可以指望回来时,我第一次学习Python的多线程。

增加循环内的睡眠通话让你的主线程块,这将允许它仍能听到和荣誉例外。 你想要做的是利用Event类的子线程,将作为一个出口标志在中断执行设定的事件。 您可以在设置该标志KeyboardInterrupt异常,只是把除了在你的主线程子句这一点。

我不能完全肯定这是怎么回事与蟒蛇特定的睡眠,并呼吁一个操作系统之间的不同的行为,但我提供的救济应您所需的最终结果是什么工作。 只是提供一个猜测,操作系统称为一个大概块解释本身以不同的方式?

请记住,通常在线程需要主线程大多数情况下是要继续执行的东西 ,在这种情况下,你简单的例子,“沉睡”将暗示。

http://docs.python.org/2/library/threading.html#event-objects



文章来源: Python threads with os.system() calls. Main thread doesn't exit on ctrl+c