Я использую Windows с Python 3.7 и пытаюсь асинхронно обмениваться данными, только строками, между процессами Python. Один из них работает бесконечно (получатель), другой может начинаться в любой момент, отправляет некоторые данные, а затем завершается (отправитель). Я пытаюсь использовать именованный канал для этого.
Мне удалось получить это, когда они работают синхронно (приемник ждет в заблокированном канале, пока не получит данные), однако у приемника есть другие вещи, которые нужно делать в идеале, ему не следует ждать все время. Также в какой-то момент может быть второй отправитель, поэтому заблокированный канал не очень хорош.
Код для получателя:
import os
import time
import sys
import win32pipe, win32file, pywintypes
pipe_name = r'\\.\pipe\mypipe'
pipe = win32pipe.CreateNamedPipe(
pipe_name,
win32pipe.PIPE_ACCESS_DUPLEX | win32file.FILE_FLAG_OVERLAPPED, # open mode
win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT, # pipe mode
1, 65536, 65536, # max instances, out buffer size, in buffer size
0, # timeout
None)
while 1:
print("doing my other stuff")
try:
win32pipe.ConnectNamedPipe(pipe, pywintypes.OVERLAPPED())
except pywintypes.error as e:
if e.winerror == 232: #disconnected pipe
win32pipe.DisconnectNamedPipe(pipe)
print("Disconnecting pipe")
else:
print(e)
try:
retval, msg = win32file.ReadFile(pipe, 0, pywintypes.OVERLAPPED())
print(msg)
except pywintypes.error as e:
if e.winerror == 536: #Wating for connection
print("waiting")
elif e.winerror == 233: #no process on other side
continue
time.sleep(1)
Код отправителя:
import os
import time
import sys
import win32pipe, win32file, pywintypes
pipe_name = r'\\.\pipe\mypipe'
for x in range(5):
handle = win32file.CreateFile(
pipe_name,
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
0,
None,
win32file.OPEN_EXISTING,
win32file.FILE_FLAG_OVERLAPPED,
None
)
res = win32pipe.SetNamedPipeHandleState(handle, win32pipe.PIPE_READMODE_MESSAGE, None, None)
print(f"sending {x}")
win32file.WriteFile(handle, str.encode(f"hello world {x}"))
win32file.CloseHandle(handle)
time.sleep(2)
Сейчас оба могут работать и иметь некоторое соединение, но я не могу получить данные. Приемник может выполнять другие операции, отключать и повторно открывать канал, если что-то отправлено, но msg
оказывается пустым. Если я остановлю его в отладчике и отправлю что-нибудь, значение msg
получит «memory at 0x0 .......», которое я бы интерпретировал как своего рода указатель, но, как вы, вероятно, уже заметили, мое понимание каналов ограничено.
Здесь Я нашел хороший пример работающего канала синхронизации. Я изменил создание трубы на приемник, но это было не сложно. Я нашел несколько примеров асинхронных (перекрывающихся) каналов здесь , которые также были великолепны, но оставили меня с проблемой, с которой я сейчас сталкиваюсь.
Чтение с перекрывающегося канала все еще является задачей для win32file.ReadFile
или я что-то пропустил?
Большое спасибо!