带有os.system()调用的Python线程.主线程不在ctrl + c上退出 [英] Python threads with os.system() calls. Main thread doesn't exit on ctrl+c

查看:726
本文介绍了带有os.system()调用的Python线程.主线程不在ctrl + c上退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读之前,请不要认为它是重复的.关于multithreadingkeyboard interrupt的问题很多,但是我没有发现任何考虑使用os.system的东西,它看起来很重要.

Please don't consider it a duplicate before reading, There are a lot of questions about multithreading and keyboard interrupt, but i didn't find any considering os.system and it looks like it's important.

我有一个python脚本,该脚本在工作线程中进行一些外部调用. 如果要按ctrl+c键,我希望它退出,但是看起来主线程忽略了它.

I have a python script which makes some external calls in worker threads. I want it to exit if I press ctrl+c But it look like the main thread ignores it.

类似这样的东西:

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),效果很好.

Surprisingly, it works fine if I change os.system("sleep 10") to time.sleep(10).

推荐答案

我不确定您使用的是哪种操作系统和外壳程序.我用zsh描述了Mac OS X和Linux(bash/sh的行为类似).

I'm not sure what operating system and shell you are using. I describe Mac OS X and Linux with zsh (bash/sh should act similar).

当您按Ctrl + C组合键时,所有在当前终端中前台运行的程序会收到信号SIGINT .在您的情况下,这是您的主要python进程以及os.system产生的所有进程.

When you hit Ctrl+C, all programs running in the foreground in your current terminal receive the signal SIGINT. In your case it's your main python process and all processes spawned by os.system.

由os.system生成的进程然后终止其执行.通常,当python脚本收到SIGINT时,它会引发KeyboardInterrupt异常,但是由于os.system(),您的主进程会忽略SIGINT. Python os.system() 调用标准C函数 system(),导致调用过程忽略SIGINT( man Linux /

Processes spawned by os.system then terminate their execution. Usually when python script receives SIGINT, it raises KeyboardInterrupt exception, but your main process ignores SIGINT, because of os.system(). Python os.system() calls the Standard C function system(), that makes calling process ignore SIGINT (man Linux / man Mac OS X).

因此,您的所有python线程都未收到SIGINT,只有子进程才能获得SIGINT.

So neither of your python threads receives SIGINT, it's only children processes who get it.

当您删除os.system()调用时,您的python进程将停止忽略SIGINT,而您得到KeyboardInterrupt.

When you remove os.system() call, your python process stops ignoring SIGINT, and you get KeyboardInterrupt.

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

You can replace os.system("sleep 10") with subprocess.call(["sleep", "10"]). subprocess.call() doesn't make your process ignore SIGINT.

这篇关于带有os.system()调用的Python线程.主线程不在ctrl + c上退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆