繁体   English   中英

Linux上python中的程序间通信

[英]Interprogram communication in python on Linux

关于如何执行这些操作的例子很多:

1)在同一程序的不同进程之间进行通信。

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

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

  • 将字符串从python程序A发送到程序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")

正如http://www.python-course.eu/pipes.php所建议的那样,读者陷入了无限循环,无法读出空字符串。

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

另一方面,所有使用更现代的低级subprocess模块的示例仅涉及多线程应用程序,而不涉及多个应用程序。 其他实现涉及套接字和网络。

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

这是预期的行为。 看看这个答案,了解类似的问题并了解FIFO行为。 与您的问题有关的部分是:

当没有更多的作家(...)时,通过read()返回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))
# 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')

笔记:

  • 使用os.open()是低级功能,没有任何意义。 您可以使用open()与命名管道进行交互。
  • 打开命名管道以读取块,直到连接了第一个写入器。 因此,在第一个客户端连接到管道之前,您不会在输出中看到“正在Listening for actions... 从没有读者的作家开始的情况也是如此。
  • 您询问“哪个阻止并处理此字符串,然后在循环中等待另一个”。 除非您在单独的线程中处理字符串,否则在处理当前字符串之前,它不会尝试读取下一个字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM