什么时候Python程序没有响应中断?

时间:2016-08-30 17:11:43

标签: python linux interrupt-handling

我在Linux上运行了一个Python3守护进程。这是一个正常的单线程进程,在后台运行,在主循环中执行task_name,然后处理I / O.有时(一个月大约1或2次)它停止响应。当它发生时,我想调试问题。

我已经尝试了select.select(),但是没有成功,因为守护进程的stdin / stdout被重定向到pyrasite设备而pyrasite使用这个stdin / stdout,而不是它启动的控制台从

所以我添加了一个/dev/null信号处理程序来记录堆栈跟踪。工作正常。

今天我冻结了。 SIGUSR1显示,该守护进程位于" S" (可中断的睡眠)状态。排除了繁忙的循环。

服务器不响应psSIGUSR(用于关闭)。

我希望至少有一些暗示那里发生了什么。

在什么条件下,睡眠的Python3 Linux进程无法处理它应该处理的中断?

更新

我终于可以重现这个问题了。在添加了大量调试消息之后,我发现了一个竞争条件,我很快就会解决。

当守护程序没有响应时,它在SIGINT处于休眠状态,其中os.read(p)是新管道的读取端(请参阅:p),其中没有人写入。

但是,我编写简单演示程序的所有尝试都失败了。当我尝试从空管读取时,程序按预期阻塞,但可能像往常一样被中断(使用SIGINT从其他终端终止)。这个谜团仍未解决。

UPDATE2:

最后一些代码!我故意选择低级系统调用。

os.pipe

如果你跑了这么多次,你就会得到这个:

import os
import time
import signal
import sys 

def sighandler(*unused):
    print("got signal", file=sys.stderr)

print("==========")
signal.signal(signal.SIGUSR1, sighandler)

pid = os.getpid()
rfd, wfd = os.pipe()
if os.fork():
    os.close(wfd)
    print("parent: read() start")
    os.read(rfd, 4096)
    print("parent: read() stop")
else:
    os.close(rfd)
    os.kill(pid, signal.SIGUSR1)
    print("child: wait start")
    time.sleep(3)
    print("child: wait end")

这很好,但有时你会看到这个:

parent: read() start
got signal
child: wait start
child: wait end
parent: read() stop

这里发生了什么:

  1. parent从管道开始读取
  2. 孩子向父母发送信号。家长必须收到这个信号,但似乎是"不知何故推迟了#34;
  3. 孩子等待
  4. 子出口,管道自动关闭
  5. 父母的阅读操作以EOF
  6. 结束
  7. 现在处理信号
  8. 现在,由于程序中的错误,在步骤2中收到了信号,但未提供EOF,因此读取未完成,并且从未达到步骤6(信号处理)。

    这是我能够提供的所有信息。

0 个答案:

没有答案