我有两个Python脚本foo.py
和bar.py
,foo.py
将通过bar.py
调用os.system()
。
#foo.py
import os
print os.getpid()
os.system("python dir/bar.py")
#bar.py
import time
time.sleep(10)
print "over"
假设foo.py
的pid为123,如果程序正常终止,则打印
123
over
如果我在kill 123
运行时输入123
Terminated
over
,我将获得以下输出
123
^CTraceback (most recent call last):
File "dir/bar.py", line 4, in <module>
time.sleep(10)
KeyboardInterrupt
如果我在运行时按 Ctrl - C ,我会得到像
这样的内容kill -SIGINT 123
但如果我在123
over
运行时键入kill 123
,程序似乎只会忽略该信号并正常退出。
kill -SIGINT 123
在我看来,
如果我输入kill -SIGINT
,则子流程不会受到影响
如果我输入 Ctrl - C ,两个进程都将被终止。
如果我在子进程运行时键入kill 123
,则信号将被忽略。
有人可以向我解释它是如何运作的吗?
是不是 Ctrl - C 和Name | Email | Phone number
alis alis@123.com +989355555;+989366666;+9803777777
John john@yah.com +989122222
sara sara@yah.com +989113212;+989113312
应该是等价的?
如果我键入Name | Email | Phone number
alis alis@123.com +989355555
alis alis@123.com +989366666
alis alis@123.com +9803777777
John john@yah.com +989122222
sara sara@yah.com +989113212
sara sara@yah.com +989113312
,是否保证子流程不会受到影响(如果它正好在运行)?
顺便说一句,我在Ubuntu 14.04上。谢谢!
答案 0 :(得分:1)
让我们依次考虑每个案例:
如果我输入
kill 123
,则子流程不会受到影响。
是的,这就是kill [pid]
的工作原理。它仅向您要杀死的进程发送信号。如果要将信号发送到一组进程,则必须使用表示process group的负数。
如果我输入Ctrl-C,则两个进程都将终止。
我认为你的意思是“由Ctrl-C终止”。实际上,情况并非如此:只有孩子被终止。如果您在foo.py
末尾添加一行print "I'm a little teapot"
,则会看到此行被打印出来。会发生什么是孩子得到信号。然后父母继续os.system
。如果没有附加行,看起来就像父亲也受到Ctrl-C的影响一样,但不是这样,正如附加行所示。
您的shell会将信号发送到与tty关联的进程组,其中包含父进程。 但是,os.system
使用system
调用阻止进行调用的进程中的SIGINT
和SIGQUIT
信号。所以父母是免疫的。
如果您不使用os.system
,那么您的流程将受SIGINT
的影响。试试foo.py
的代码:
import os
import subprocess
print os.getpid()
p = subprocess.Popen(["python", "dir/bar.py"])
p.wait()
print "I'm a little teapot"
如果在运行时按Ctrl-C,您将获得两个回溯:一个来自父级,一个来自子级:
$ python foo.py
29626
^CTraceback (most recent call last):
File "dir/bar.py", line 4, in <module>
Traceback (most recent call last):
File "foo.py", line 8, in <module>
time.sleep(10)
KeyboardInterrupt p.wait()
File "/usr/lib/python2.7/subprocess.py", line 1389, in wait
pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
File "/usr/lib/python2.7/subprocess.py", line 476, in _eintr_retry_call
return func(*args)
KeyboardInterrupt
如果在子进程运行时键入
kill -SIGINT 123
,则信号将被忽略。
见上文。
不是Ctrl-C和
kill -SIGINT
应该是等价的吗?
Ctrl-C会将SIGINT
发送到与您发出Ctrl-C的tty相关联的前台进程组。
如果我输入
kill 123
,是否保证子流程不会受到影响(如果它正好在运行)?
本身kill 123
只会将信号发送给pid
123的进程。儿童不会受到影响。