Why does os.path.exists() stop windows named pipes from connecting?

帅比萌擦擦* 提交于 2021-02-10 09:32:19

问题


It seems that a successful test of the existence of a windows named pipe by using os.path.exists() prevents the pipe from working. Why would this be?

Here is successfully working windows named-pipe code:

import time
import multiprocessing as mp
import win32pipe, win32file

PIPENAME = r'\\.\pipe\Foo'

def producer(pipe_name: str):
    print('producer')
#    if not os.path.exists(pipe_name):
#        print(f'No pipe {pipe_name}')
#        return
    pipe = win32file.CreateFile(pipe_name,
                                win32file.GENERIC_READ | win32file.GENERIC_WRITE,  # dwDesiredAccess
                                0,  # dwShareMode
                                None,  # lpSecurityAttributes
                                win32file.OPEN_EXISTING,  # dwCreationDisposition
                                0,  # dwFlagsAndAttributes
                                None
                                )
    win32pipe.SetNamedPipeHandleState(pipe, win32pipe.PIPE_READMODE_MESSAGE, None, None)
    win32file.WriteFile(pipe, b'foobar')


def receiver(pipe_name: str):
    print('receiver')
    pipe = win32pipe.CreateNamedPipe(pipe_name,
                                     win32pipe.PIPE_ACCESS_DUPLEX,
                                     win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT,
                                     1,  # nMaxInstances
                                     65536,  # nOutBufferSize
                                     65536,  # nInBufferSize
                                     0, # 50ms timeout (the default)
                                     None) # securityAttributes
    win32pipe.ConnectNamedPipe(pipe)
    msg = win32file.ReadFile(pipe, 65536)
    print(f'msg: {msg}')

if __name__ == '__main__':
    recv_p = mp.Process(target=receiver, args=(PIPENAME,))
    prod_p = mp.Process(target=producer, args=(PIPENAME,))
    recv_p.start()
    time.sleep(0.1)
    prod_p.start()
    prod_p.join()
    recv_p.join()enter code here

This works as expected, with the receiver printing the received message.

But if the three commented-out lines in the producer are uncommented, the os.path.exists(pipe_name) call somehow breaks the pipe so the output becomes:

receiver
producer
Process Process-2:
Process Process-1:
Traceback (most recent call last):
  File "C:\Users\redacted\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 297, in _bootstrap
    self.run()
  File "C:\Users\redacted\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "C:\git\redacted\named_pipe_mqtt_test.py", line 18, in producer
    None
pywintypes.error: (231, 'CreateFile', 'All pipe instances are busy.')
Traceback (most recent call last):
  File "C:\Users\redacted\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 297, in _bootstrap
    self.run()
  File "C:\Users\redacted\AppData\Local\Programs\Python\Python37\lib\multiprocessing\process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "C:\git\redacted\named_pipe_mqtt_test.py", line 35, in receiver
    msg = win32file.ReadFile(pipe, 65536)
pywintypes.error: (109, 'ReadFile', 'The pipe has been ended.')

Why would os.path.exists break windows named pipes?

I've ruled out the python multiprocessing library. I've tried a delay after os.path.exists.

This is not a blocking problem for me, but I am curious.

来源:https://stackoverflow.com/questions/51255352/why-does-os-path-exists-stop-windows-named-pipes-from-connecting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!