由于我不打算进入的原因,我需要在FreeBSD 8.1上的Python线程的子进程中运行'top -m io -d 2 10'的变体.麻烦的是,似乎有时会产生SIGTTOU(在某些依赖于代码的条件下,我还没有破译),完全停止顶部和线程.其他时候,似乎没有生产SIGTTOU,但无论如何顶部或线程都会卡住.
top的输出应该为系统中的前10个进程生成两组IO统计数据,其中第一组是"绝对"数字,第二组是自上一组以来的统计数据的增量差异,比之前提前一秒.在终端或shell脚本中运行此命令,无论是否重定向输出,都可以正常工作.
当问题发生时,似乎'top'写入第一组输出,但在它输出第二组之前挂起/接收SIGTTOU.在下面的示例代码中,只有一组进程统计信息被写入输出文件.
我在'truss'下发现了运行python脚本的SIGTTOU信号,但似乎'truss'和'top'之间的交互本身可能是一个混乱的问题,因为简单的运行truss top -d 2产生信号并挂起,如下所示:
...
ioctl(1,TIOCGETA,0xffffe460) = 0 (0x0)
ioctl(1,TIOCGETA,0xc6b138) = 0 (0x0)
ioctl(1,TIOCGETA,0xffffe410) = 0 (0x0)
ioctl(1,TIOCGWINSZ,0xffffe460) = 0 (0x0)
ioctl(1,TIOCGWINSZ,0xffffe930) = 0 (0x0)
ioctl(1,TIOCGETA,0x50e560) = 0 (0x0)
sigprocmask(SIG_BLOCK,SIGINT|SIGQUIT|SIGTSTP,0x0) = 0 (0x0)
ioctl(1,TIOCGETA,0x50e560) = 0 (0x0)
SIGNAL 22 (SIGTTOU)
Run Code Online (Sandbox Code Playgroud)
这是一个示例Python脚本,它可以重现hang和/或SIGTTOU:
import subprocess
from threading import Thread
def run():
with open("top.log", "wb") as f:
subprocess.Popen(("/usr/bin/top", "-m", "io", "-d", "2", "10"), stdout=f, stderr=f, stdin=subprocess.PIPE).communicate()
if __name__ == "__main__":
th = …Run Code Online (Sandbox Code Playgroud)