UNIX命名管道文件结束

3 投票
5 回答
1916 浏览
提问于 2025-04-17 03:00

我正在尝试使用Unix命名管道来输出一个正在运行的服务的统计信息。我想提供一个类似于/proc的接口,这样人们可以通过查看一个文件来看到实时的统计数据。

在我的Python代码中,我使用了类似下面的代码:

while True:
  f = open('/tmp/readstatshere', 'w')
  f.write('some interesting stats\n')
  f.close()

/tmp/readstatshere是通过mknod创建的一个命名管道。

然后我用cat命令来查看统计信息:

$ cat /tmp/readstatshere
some interesting stats

大部分时候这个方法都能正常工作。不过,如果我快速连续地多次使用cat命令,有时会得到多行some interesting stats,而不是一行。有一两次,它甚至进入了一个无限循环,永远打印那一行,直到我强制结束它。到目前为止,我唯一找到的解决办法是在f.close()之后加一个大约500毫秒的延迟,以防止这个问题。

我想知道这到底是为什么,以及是否有更好的处理方法。

提前谢谢你!

5 个回答

1

我觉得你应该使用fuse。它有Python的接口,可以查看这个链接:http://pypi.python.org/pypi/fuse-python/。这样你就可以把问题的答案组合成类似于posix文件系统的调用方式。

1

那用UNIX套接字代替管道怎么样呢?

在这种情况下,你可以在每次连接时及时提供新的数据。

唯一的缺点是你不能用cat命令来查看数据;你需要创建一个新的套接字句柄,并且用connect()去连接这个套接字文件。

MYSOCKETFILE = '/tmp/mysocket'
import socket
import os
try:
    os.unlink(MYSOCKETFILE)
except OSError: pass
s = socket.socket(socket.AF_UNIX)
s.bind(MYSOCKETFILE)
s.listen(10)
while True:
    s2, peeraddr = s.accept()
    s2.send('These are my actual data')
    s2.close()

查询这个套接字的程序:

MYSOCKETFILE = '/tmp/mysocket'
import socket
import os
s = socket.socket(socket.AF_UNIX)
s.connect(MYSOCKETFILE)
while True:
    d = s.recv(100)
    if not d: break
    print d
s.close()
1

在这里,使用管道根本不是个好主意。如果你想展示你程序内部状态的一个稳定快照,可以先把这个状态写入一个临时文件,然后再把它改名为“公开”的名字。这样可以避免在你更新状态时,其他进程读取到不一致的数据。同时,千万不要在一个忙碌的循环中这样做,最好是在一个线程里,每次更新之间让它休眠至少一秒钟。

撰写回答