如何调试一个奇怪的线程打开fifo问题?

时间:2009-03-20 19:01:14

标签: python multithreading stream fifo inetd

Web服务配置为在接收USR1信号时公开其部分数据。当xinetd服务器收到来自远程客户端的请求时,信号将由xinetd服务器发送,例如, nc myserver 50666.当Web服务器收到USR1信号时,它会打开一个专用的fifo管道,将其数据写入管道,然后关闭管道。与此同时,xinetd服务器读取管道并将其提供给远程客户端。

在大多数情况下,它们运行良好但偶尔会出于某种原因,客户端将收到重复记录。从日志中,似乎管道没有正确关闭并且缓存是剩余的,因此当下次服务时,前一个和当前都被发送到客户端。问题是它在尝试重现时不会经常发生,不幸的是,我无法重现一次。

以下是演示该过程的简单片段:

网络服务器:(webserver.py)

def SendStream(data, pipe):
  try:
    for i in data:
      pipe.write(i + '\n') 
      pipe.flush()
  finally:
      pipe.close()

def Serve():
  threading.Thread(target=SendStream, args=(data, pipe)).start()

xinetd.d服务器:(spitter.py)

def Serve():
  if not os.path.exists(PIPE_FILE):
    os.mkfifo(PIPE_FILE)
  os.kill(server_pid, signal.SIGUSR1)
  for i in open(PIPE_FILE):
    print i,

那究竟发生了什么导致重复?怎么触发它?当前的修复程序我取消链接管道文件并每次重新创建它以避免任何剩余,但我不知道这是否是一个正确的解决方案。

3 个答案:

答案 0 :(得分:0)

如果你同时运行两个splitter.py副本,就会出现问题,而且几乎所有发生在你身上的事都是合法的。尝试将进程ID值添加到webserver.py,即:

pipe.write(str(os.getpid())+ i +'\ n')

这可能很有启发性。

答案 1 :(得分:0)

这里没有足够的调试。您没有显示服务器如何处理信号或打开管道。

如果可能,我建议不要使用信号。它们在C语言中非常毛茸茸,没有注意到python自身特有的特性。

答案 2 :(得分:0)

所以真正的问题是存在多个客户端。服务器已被其他未知客户端查询/滥用,这些客户最初未与客户达成一致,并确定它将在当前设计下破解。已部署修复程序以解决此问题。所以安迪的怀疑是正确的。多谢你们!