我正在使用Windows与Python 3.7,我正在尝试异步共享数据,ony字符串,在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
的值得到“内存在0x0 .......”,我将其解释为某种指针,但是当你probalby已经注意到我对管道的理解是有限的。
Here我找到了一个有效的同步管道的好例子。我将管道的创建改为接收器,但这并不难。我找到了异步(重叠)管道here的一些例子,它们也很棒,但让我知道我现在面临的问题。
我从重叠的管道读取仍然是win32file.ReadFile
or的任务是他缺少的东西?
非常感谢你!
我找到了解决方案并希望分享它,以防万一其他人在这个问题上磕磕绊绊。事实证明msg
得到“内存在0x0 .......”是一个memoryview对象,其数据可以通过bytes(msg)
公开。
我的ReadFile
命令也存在问题,因为缓冲区必须> 0才能实现任何目标。现在它分别读取每个字节并将它们添加到字符串中。这在性能方面可能不是很好,但它对我有用,并且它解决了如果消息短于缓冲区长度必须削减结束的问题。
msg = ''
rtnvalue, data = win32file.ReadFile(pipe, 1, pywintypes.OVERLAPPED())
while rtnvalue == 234:
msg = msg + bytes(data).decode('ASCII')
rtnvalue, data = win32file.ReadFile(pipe, 1, pywintypes.OVERLAPPED())
if rtnvalue == 0: #end of stream is reached
msg = msg + bytes(data).decode('ASCII')
return msg