使用子进程 PIPE 在 Python 脚本之间发送字符串 [英] Sending strings between to Python Scripts using subprocess PIPEs

查看:48
本文介绍了使用子进程 PIPE 在 Python 脚本之间发送字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的主 Python 程序中使用子进程打开一个 Python 脚本.我希望这两个程序在运行时能够相互聊天,以便我可以监视从属脚本中的活动,即我需要它们在彼此之间发送字符串.

I want to open a Python script using subprocess in my main python program. I want these two programs to be able to chat with one another as they are both running so I can monitor the activity in the slave script, i.e. I need them to send strings between each other.

主程序将有一个与此类似的功能,它将与从属脚本通信并监视:

The main program will have a function similar to this that will communicate with and monitor the slave script:

脚本 1

import subprocess
import pickle
import sys
import time
import os

def communicate(clock_speed, channel_number, frequency):
    p = subprocess.Popen(['C:\\Python27\\pythonw','test.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    data = pickle.dumps([clock_speed, channel_number, frequency]).replace("\n", "\\()")
    print data
    p.stdin.write("Start\n")
    print p.stdout.read()
    p.stdin.write(data + "\n")
    p.poll()
    print p.stdout.readline()
    print "return:" + p.stdout.readline()
    #p.kill()

if __name__ == '__main__':
    print "GO"
    communicate(clock_speed = 400, channel_number = 0, frequency = 5*1e6)

test.py 脚本看起来像这样:

The test.py script looks similar to this:

脚本 2

import ctypes
import pickle
import time
import sys

start = raw_input("")
sys.stdout.write("Ready For Data")
data = raw_input("")
data = pickle.loads(data.replace("\\()", "\n"))
sys.stdout.write(str(data))
###BUNCH OF OTHER STUFF###

我希望这些脚本执行以下操作:

What I want these scripts to do is the following:

  1. 脚本 1 使用 Popen 打开脚本 2
  2. 脚本 1 发送字符串Start\n"
  3. 脚本 2 读取此字符串并发送字符串Ready For Data"
  4. 脚本 1 读取此字符串并将腌制数据发送到脚本 2
  5. 那么无论如何...

主要问题是如何做第 2-4 部分.然后应该遵循两个脚本之间的其余通信.截至目前,我只能在终止后从脚本 2 中读取字符串.

The main question is how to do parts 2-4. Then the rest of the communication between the two scripts should follow. As of now, I have only been able to read the strings from Script 2 after it has been terminated.

非常感谢任何帮助.

更新:

脚本 1 必须使用 32 位 Python 运行,而脚本 2 必须使用 64 位 Python 运行.

Script 1 must be run using 32-bit Python, while Script 2 must be run using 64-bit Python.

推荐答案

pipe 的问题是,如果你调用了一个读操作,却没有东西可以读,你的代码就会停滞,直到对方写了一些东西让你读.此外,如果您写入过多,您的下一个写入操作可能会阻塞,直到另一方从管道中读取某些内容并将其释放.

The problem with pipes is that if you call a read operation and there is nothing to read, your code is stalled until the other party writes something for you to read. Also if you write too much, your next write operation might block until the other party reads something out of the pipe and frees it.

您可以进行非阻塞调用",在这些情况下会返回错误而不是阻塞,但您的应用程序仍然需要明智地处理错误.

There are "non-blocking calls" you can make, that will return an error in these cases instead of blocking, but your application will still need to deal with the errors sensibly.

无论如何,您需要设置某种协议.想想 HTTP 或您熟悉的任何其他协议:有请求和响应,当您阅读这两者中的任何一个时,协议总是会告诉您是否还有其他内容需要阅读.这样,您始终可以就是否等待更多数据做出明智的决定.

In any case, you need to set up some kind of protocol. Think of HTTP, or any other protocol you know well: there are requests and responses, and while you are reading either of the two the protocol always tells you if there is something else you need to read or not. That way you can always make an informed decision on whether to wait for more data or not.

这是一个有效的例子.它有效,因为有以下协议:

Here is an example that works. It works because there is the following protocol:

  • p1 发送一行,以 '\n' 结尾;
  • p2 也一样;
  • p1 发送另一行;
  • p2 也一样;
  • 两个人都很高兴并退出.

为了向管道(在任一侧)写入一行并确保它进入管道,我调用 write() 然后调用 flush().

In order to write a line to the pipe (on either side) and make sure it gets onto the pipe, I call write() and then flush().

为了从管道(在任一侧)读取一行,而不是多一个字节,从而阻塞我的代码,直到该行准备好并且不再超过该行,我使用 readline().

In order to read a single line from the pipe (on either side) but not a single byte more, thus blocking my code until the line is ready and no longer than that, I use readline().

您还可以进行其他调用和其他协议,包括现成的协议,但单行协议适用于简单的事情和这样的演示.

There are other calls you could make and other protocols, including ready-made ones, but the single-line protocol works well for simple things and for a demo like this.

p1.py:

import subprocess

p = subprocess.Popen(['python', 'p2.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.write("Hello\n")
p.stdin.flush()
print 'got', p.stdout.readline().strip()
p.stdin.write("How are you?\n")
p.stdin.flush()
print 'got', p.stdout.readline().strip()

p2.py:

import sys

data = sys.stdin.readline()
sys.stdout.write("Hm.\n")
sys.stdout.flush()
data = sys.stdin.readline()
sys.stdout.write("Whatever.\n")
sys.stdout.flush()

这篇关于使用子进程 PIPE 在 Python 脚本之间发送字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆