Issue
My goal is to open a named pipe asynchronously. Unfortunately the pipe blocks until it is also opened from the other side. Thus, to prevent my application from blocking I am performing this call in a separate thread. The problem is, that I have no way of cancelling this thread.
import asyncio
import signal
async def connect_pipe(pipe):
print(f"Connecting to {pipe}")
loop = asyncio.get_event_loop()
try:
pipe = await asyncio.to_thread(open, pipe, "rb", 0)
print(f"Connected to {pipe}")
except asyncio.CancelledError:
print(f"Connecting to {pipe} was interrupted")
def exit_handler():
task.cancel()
loop.stop()
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, exit_handler)
task = loop.create_task(connect_pipe("/path/to/pipe"))
print("Hello World")
loop.run_forever()
loop.close()
If you run this script you should see Hello World printed. If you connect to the script by doing something like: echo "Hello" > /path/to/pipe
it should print Connected to to the console. If you try to exit, the program closes as expected. However, if you don't connect to the pipe and try to exit, the program will hang because it can't cancel the running thread.
The question is similar to this one: python asyncio - cancelling a `to_thread` task won't stop the thread In this case the use of threading.Event is suggested. But this won't work in my case since I am performing a single blocking call. What can I do?
Solution
I think I have found the solution. The key is to use os.open(pipe, os.O_RDONLY | os.O_NONBLOCK)
This will return a file descriptor which can be opened using os.fdopen
. In case you want to write to a pipe you do os.open(pipe, os.O_WRONLY | os.O_NONBLOCK)
This will throw an exception if the pipe is not connected to a reader. For other people with the same problem, this might be helpful: Can I open a named pipe on Linux for non-blocked writing in Python?
Answered By - BlackCatCoder
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.