Solaris 10上的Python 2.7.3
问题
背景和代码
我有一个首先生成工作管理线程的python脚本。然后,工作线程管理线程生成一个或多个工作线程。我的主线程中还有其他一些我无法阻止的东西。我的管理线程和工作线程是坚如磐石的。我的服务运行多年没有重新启动,但我们有subprocess.Popen
方案:
在工作线程的run方法中,我正在使用:
class workerThread(threading.Thread):
def __init__(self) :
super(workerThread, self).__init__()
...
def run(self)
...
atempfile = tempfile.NamedTempFile(delete=False)
myprocess = subprocess.Popen( ['third-party-cmd', 'with', 'arguments'], shell=False, stdin=subprocess.PIPE, stdout=atempfile, stderr=subprocess.STDOUT,close_fds=True)
...
我需要使用myprocess.poll()
来检查进程终止,因为我需要扫描atempfile
,直到找到相关信息(文件可能> 1 GiB)并且我需要终止进程因为用户请求或因为进程运行时间过长。一旦找到我要找的东西,我就会停止检查stdout临时文件。我将在外部进程停止并且工作线程终止之前将其清理干净。我需要stdin PIPE,以防我需要在孩子的stdin流中注入一些交互式的响应。
在我的主程序中,如果我的主python程序使用SIGTERM或SIGINT(Ctrl-C)终止(如果从shell运行),我为我设置一个SIGINT和SIGTERM处理程序来执行清理。
有没有人有一个坚实的2.x配方用于线程中的子信号处理? ctypes sigprocmask等。
非常感谢任何帮助。我只是在寻找一位官员'食谱或最佳黑客,如果有的话。
备注
我正在使用受限制的Python构建。我必须使用2.7.3。第三方cmd是我没有源代码的程序 - 修改它是不可能的。
答案 0 :(得分:1)
你的描述中有很多东西看起来很奇怪。首先,您有几个不同的线程和进程。谁崩溃,谁接收SIGTERM,谁接收SIGKILL以及由于哪些操作?
第二:为什么你的父母会收到SIGTERM?它无法隐式发送。有人直接或间接地向您的父进程调用kill(例如,通过终止整个父组)。
第三点:当您处理SIGTERM时,您的程序如何终止?根据定义,如果没有处理,程序将终止。如果它被处理,它不会被终止。真的发生了什么?
建议:
$ cat crsh.c
#include <stdio.h>
int main(void)
{
int *f = 0x0;
puts("Crashing");
*f = 0;
puts("Crashed");
return 0;
}
$ cat a.py
import subprocess, sys
print('begin')
p = subprocess.Popen('./crsh')
a = raw_input()
print(a)
p.wait()
print('end')
$ python a.py
begin
Crashing
abcd
abcd
end
这很有效。没有信号传递给父母。你有没有在程序中找出问题?
如果问题是发送到多个进程的信号:您是否可以使用setpgid为子进程设置单独的进程组?
是否有任何理由创建临时文件?它是在临时目录中创建的1 GB文件。为什么不管道stdout?
如果您确定需要在父程序中处理信号(为什么不尝试/除了KeyboardInterrupt,例如?):可能使用多线程程序发出信号()未指定的行为会导致这些问题(对于例如,将信号分派给不处理信号的线程??
NOTES
The effects of signal() in a multithreaded process are unspecified.
无论如何,尝试更精确地解释你的程序的线程和过程是什么,他们做了什么,信号处理程序是如何设置的,为什么,谁在发送信号,谁在接收等等,等等。