简体   繁体   中英

Using stdout and stdin in a loop in python leading to errors

I am using stdout and stdin to communicate information between two python programs. tester.py should pass telemetry data into helper.py and helper.py should return some command to tester.py.

This seems to work when run without a loop, but when I put the code in tester.py inside a loop that updates the telemetry data, helper.py no longer seems able to pass back the correct command. The console print out is as follows:

b'\x00\x00\x00\x00\x01\x00\x00\x00'
0.0
b''
Traceback (most recent call last):
  File "/Users/Advay/Documents/PyCharm/zip_sim/tester.py", line 44, in <module>
    varr = COMMAND_STRUCT.unpack(cmd)
struct.error: unpack requires a buffer of 8 bytes

The tester.py:

import sys
import subprocess
import struct

TELEMETRY_STRUCT = struct.Struct(">fB3s")
COMMAND_STRUCT = struct.Struct(">fB3s")
helper = subprocess.Popen(['python3', 'helper.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

drop = 1
padding = bytes(3)

for i in range(5):

    speed = i

    helper.stdin.write(TELEMETRY_STRUCT.pack(speed, drop, padding))
    helper.stdin.flush()

    cmd = helper.stdout.read(COMMAND_STRUCT.size)
    print(cmd)
    varr = COMMAND_STRUCT.unpack(cmd)
    print(varr[0])

and the helper.py:

import os
import random
import sys
import struct

TELEMETRY_STRUCT = struct.Struct(">fB3s")
COMMAND_STRUCT = struct.Struct(">fB3s")

telemetry = sys.stdin.buffer.read(TELEMETRY_STRUCT.size)
a = TELEMETRY_STRUCT.unpack(telemetry)

command = COMMAND_STRUCT.pack(a[0], 1, bytes(3))

sys.stdout.buffer.write(command)
sys.stdout.buffer.flush()

Any help would be appreciated a lot, I am at a complete loss as to why it. does not work in the loop.

You're trying to send multiple commands from tester.py to helper.py , but helper.py only reads a single command and then exits -- there is no loop that would allow it to continue receiving additional commands from tester.py .

When you run tester.py , the first loop iteration succeeds, but the subsequent iteration fails because the helper.stdout.read() returns an empty value (because the helper has exited).

You need to structure your helper.py so that it can receive multiple commands.

For example:

import os
import random
import sys
import struct

TELEMETRY_STRUCT = struct.Struct(">fB3s")
COMMAND_STRUCT = struct.Struct(">fB3s")

while True:
    telemetry = sys.stdin.buffer.read(TELEMETRY_STRUCT.size)
    if not telemetry:
        break

    a = TELEMETRY_STRUCT.unpack(telemetry)

    command = COMMAND_STRUCT.pack(a[0], 1, bytes(3))

    sys.stdout.buffer.write(command)
    sys.stdout.buffer.flush()

With this change, running tester.py results in:

b'\x00\x00\x00\x00\x01\x00\x00\x00'
0.0
b'?\x80\x00\x00\x01\x00\x00\x00'
1.0
b'@\x00\x00\x00\x01\x00\x00\x00'
2.0
b'@@\x00\x00\x01\x00\x00\x00'
3.0
b'@\x80\x00\x00\x01\x00\x00\x00'
4.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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