python线程和进程之间管道的不同行为?

时间:2014-02-06 20:57:36

标签: python linux multithreading pipe

我有一个python脚本,在调用时将一些数据写入管道:

def send_to_pipe(s):
    send = '/var/tmp/mypipe.pipe'
    sp = open(send, 'w')
    sp.write(json.dumps(s))
    sp.close()

if __name__ == "__main__":
    name = sys.argv[1]
    command = sys.argv[2]
    s = {"name":name, "command":command}
    send_to_pipe(s)

然后我有这个文件无限期地打开管道并在每次调用上面的脚本时读取数据:

def watch_pipe():
    receive = '/var/tmp/mypipe.pipe'
    os.mkfifo(receive)
    rp = os.open(receive, os.O_RDWR | os.O_NONBLOCK)
    p = select.poll()
    p.register(rp, select.POLLIN)
    while True:
        try:
            if p.poll()[0][1] == select.POLLIN:
                data = os.read(rp,512)
                # Do some stuff with the data
        except:
            os.close(rp)
            os.unlink(receive)

if __name__ == "__main__":
        t = Thread(target=watch_pipe)
        t.start()
        # Do some other stuff that goes on indefinitely

当我使用线程时,此代码非常有效。管道保持打开状态,第一个文件写入管道,然后完成任务。问题是我想关闭程序时无法停止线程。所以我从Thread切换到Process:

        p = Process(target=watch_pipe)
        p.start()

但是使用进程而不是线程,当我运行编写器脚本时,open(send, 'w')会删除管道,就好像它是我想要覆盖的文件一样。为什么是这样?在这两种情况下,文件的权限和所有权都是相同的,并且编写器脚本不会更改。唯一改变的是用类似的Process对象替换Thread对象。

编辑:更改打开后使用'a'而不是'w',管道在使用过程时仍然会消失。

2 个答案:

答案 0 :(得分:0)

只是一个想法,为您的文件使用其他打开模式,例如"a"而不是"w"。确实,"w"截断文件,"a"仅附加到文件。

我可以想象当你使用线程时,即在一个相同的进程中,当你打开它进行写入时,管道文件已经打开以供阅读。在这种情况下,开放写作可能不会截断文件。与进程相反,写入过程不知道文件是否已打开以进行读取,并且可能会将其删除以截断它。

答案 1 :(得分:0)

你为什么要对自己造成困难?您在一个线程中使用的例程中打开了FIFO作为O_RDWR。如果你想关闭线程,只要让其它线程关闭它,就可以向FIFO写一个“停止”消息。线程读取消息,关闭自己,所有的一切都是正确的世界。没有大惊小怪,没有麻烦,不需要单独的过程。