Myślę, że być może po prostu nie widzisz wyjścia z tego, co się dzieje. Oto pełny przykład, który wydaje się działać na moim polu, chyba że całkowicie nie rozumiem tego, co chcesz. Główną zmianą, którą wprowadziłem, jest ustawienie stdout
dla p
na zamiast na subprocess.PIPE
. Może jestem nieporozumienie ciąg na swoje pytanie, a bit jest kluczowym ...
Oto pełny kod i wyjście:
W wysyłającego (testing) proces (nazwałem go test_comms.py). Jestem obecnie na Windows, więc przepraszam za .bat
:
import time
import subprocess
import sys
# Note I'm sending stdout to sys.stdout for observation purposes
p = subprocess.Popen(args = 'myapp.bat',
stdin = subprocess.PIPE,
stdout = sys.stdout,
universal_newlines=True)
#Send 10 messages to the process's stdin, 1 second apart
for i in range(10):
time.sleep(1)
p.stdin.write('my message\n')
myapp.bat jest trywialnie:
echo "In the bat cave (script)"
python myapp.py
myapp.py zawiera (używając Queue
zamiast queue
- obecnego środowiska Python 2):
import Queue
from Queue import Empty
import threading
import sys
import time
def get_input():
print("Started the listening thread")
for line in iter(sys.stdin.readline, ''):
print("line arrived to put on the queue\n")
q.put(line)
sys.stdin.close()
print("Hi, I'm here via popen")
q = Queue.Queue()
threading.Thread(name = 'input-getter',
target = get_input).start()
print("stdin listener Thread created and started")
# Read off the queue - note it's being filled asynchronously based on
# When it receives messages. I set the read interval below to 2 seconds
# to illustrate the queue filling and emptying.
while True:
time.sleep(2)
try:
print('Queue size is',q.qsize())
print('input:', q.get_nowait())
except Empty:
print('no input')
print("Past my end of code...")
wyjściowa:
D:\>comms_test.py
D:\>echo "In the bat cave (script)"
"In the bat cave (script)"
D:\>python myapp.py
Hi, I'm here via popen
Started the listening threadstdin listener Thread created and started
line arrived to put on the queue
line arrived to put on the queue
('Queue size is', 2)
('input:', 'my message\n')
line arrived to put on the queue
line arrived to put on the queue
('Queue size is', 3)
('input:', 'my message\n')
line arrived to put on the queue
line arrived to put on the queue
('Queue size is', 4)
('input:', 'my message\n')
line arrived to put on the queue
line arrived to put on the queue
('Queue size is', 5)
('input:', 'my message\n')
line arrived to put on the queue
line arrived to put on the queue
D:\>('Queue size is', 6)
('input:', 'my message\n')
('Queue size is', 5)
('input:', 'my message\n')
('Queue size is', 4)
('input:', 'my message\n')
('Queue size is', 3)
('input:', 'my message\n')
('Queue size is', 2)
('input:', 'my message\n')
('Queue size is', 1)
('input:', 'my message\n')
('Queue size is', 0)
no input
('Queue size is', 0)
no input
('Queue size is', 0)
no input
Jeśli nie chcesz zakończyć procesu, nie powinieneś używać polecenia "komunikuj się" (wysyła tylko te dane, a następnie czeka, aż proces się zakończy); zamiast tego napisz bezpośrednio do 'p.stdin'. – poke
'stdin.flush()'? A co powiesz na używanie modułu takiego jak [async_subprocess] (https://pypi.python.org/pypi/async_subprocess/0.2.1)? –
@InbarRose już wypróbował to .. nie szczęście .. –