Linux上python的程序间通信

Linux上python的程序间通信,python,linux,io,Python,Linux,Io,有很多关于如何做这些事情的例子: 1) 同一程序中不同进程之间的通信 2) 通过网络在客户端/服务器之间通信 然而,这个问题在我看过的任何地方都没有很好的例子: 从python程序a向程序B发送字符串的规范方法是什么,程序B阻塞并处理该字符串,然后在循环中等待另一个字符串 我觉得我已经接近一个答案很多次,但从来没有设法创造一个工作的例子 其他隐含要求: 实际上是两个不同的程序:该示例需要实际有两个不同的程序(即,两个文件progA.py、progB.py,可以在同一台机器上的两个屏幕上从命

有很多关于如何做这些事情的例子:

1) 同一程序中不同进程之间的通信

2) 通过网络在客户端/服务器之间通信

然而,这个问题在我看过的任何地方都没有很好的例子:

  • 从python程序a向程序B发送字符串的规范方法是什么,程序B阻塞并处理该字符串,然后在循环中等待另一个字符串
我觉得我已经接近一个答案很多次,但从来没有设法创造一个工作的例子

其他隐含要求:

  • 实际上是两个不同的程序:该示例需要实际有两个不同的程序(即,两个文件progA.py、progB.py,可以在同一台机器上的两个屏幕上从命令行分别运行),而不使用任何类型的分叉或多进程来创建客户机和服务器
  • 请建议一种方法,允许发送长度不超过合理长度的可变长度分隔字符串,而不必获得数据大小的准确字节数。(后者在实现中更容易出错)
  • 理想情况下,在不使用本地主机internet连接的情况下执行此操作
比如,;当读者使用:

pipein = open(pipe_name, 'r')
while program.KeepRunning:
    action = pipein.readline()[:-1]
    program.processLine(line)
    time.sleep(1)
作者使用:

command = "enable"
pipeout = os.open(pipe_name, os.O_WRONLY)
os.write(pipeout, command)
os.write(pipeout, "\n")
正如在 读取器陷入无限循环中,无法读取空字符串

有趣的是,将
if(action=='enable'):longFunction()添加到
程序.processLine
函数会导致执行
longFunction
中的部分代码,直到永远无法读取空行

另一方面,所有使用较现代、较低级的
子流程
模块的示例只涉及多线程应用程序,而不涉及多个应用程序。其他实现包括套接字和网络


当我尝试使用套接字时,这会导致一般的“出错”类型错误,有许多可能的原因
错误111:“连接被拒绝”
显示“有时”。作为python代码的一部分,在接收到某些命令时执行的python代码实际上修改了网络配置(例如,它调用诸如
ip
tc
iptables
等命令,并带有各种参数),使用到
localhost
的网络连接可能是应该避免的,导致难以调试和通常令人讨厌的问题。除了第二个程序在同一台机器上运行时不需要的部分之外,任何程序间通信都不需要使用网络接口

这是预期的行为。查看类似问题和FIFO行为概述。与你的问题相关的部分是:

当没有更多的写入程序(…)时,通过返回
EOF
来通知读者这一点

file.readline()
表示
'
(空字符串)表示已达到
EOF

如果
f.readline()
返回一个空字符串,则已到达文件末尾,而空行由
'\n'
表示,该字符串仅包含一个换行符

就这样。在无限循环中,每次尝试读取时,都会得到一个空字符串,表示没有更多的写入程序连接

没有什么可以阻止您使用命名管道来解决任务。最简单的方法就是在没有作家的时候睡一段时间。以下是工作示例:

# server.py

import os
import time

pipe_name = 'pipe_test'

if not os.path.exists(pipe_name):
    os.mkfifo(pipe_name)

with open(pipe_name, 'r') as pipe:
    print("Listening for actions...")
    while True:
        action = pipe.readline()[:-1]
        if action == '':
            print("No clients. Sleeping...")
            time.sleep(1)
        else:
            print("Action received:", repr(action))
注:

  • 使用
    os.open()
    ,这是一个低级函数,没有任何意义。您可以使用
    open()
    与命名管道交互
  • 打开命名管道进行读取,直到连接第一个写入程序。因此,在第一个客户端连接到管道之前,您不会在输出中看到
    侦听操作…
    。没有读者的作家也是如此
  • 您询问“哪些块和处理此字符串,然后在循环中等待另一个”。除非您在单独的线程中处理该字符串,否则在处理当前字符串之前,它不会尝试读取下一个字符串

你试过好答案吗。有一件事:为什么要使用
[:-1]
?如果我理解正确,如果客户端在服务器睡眠时向管道中添加了多行,则只读取最后一行。
f.readline()
返回带有尾随的行
\n
,因此
[:-1]
用于从字符串末尾除去此
\n
。否,当进程唤醒时,将处理在睡眠期间添加的所有行。您可以通过增加睡眠时间和在睡眠时间发送多行代码来测试它。服务器休眠时,管道存储所有行。
# client.py

import os

pipe_name = 'pipe_test'

if not os.path.exists(pipe_name):
    os.mkfifo(pipe_name)

print("Waiting for server to start...")
with open(pipe_name, 'w') as pipe:
    action = input("Enter action to send: ")
    pipe.write(action + '\n')