How do you make blocking writes on a pipe? #1388
Replies: 1 comment
-
Note that if you set O_NONBLOCK the worker thread will sometimes return without writing as expected. This makes me think that for io_uring O_NONBLOCK only makes the write "poll" for any space, but not to block until the entire write is complete. I know that for a correct program you will need to each "logical" write to be a loop anyway, adjusting based on how much you have already written; however, it seems like without adjusting the pipe size, you will need issue many sqe's for large pipe writes. E.g. if the reader is never concurrent with the writer, then for each 1MB write and 64KiB pipe size, you will need to issue at 16 sqes, and for each 1GiB you would need to issue around 64K SQEs (which for me seems to be degrading performance, but I am doing more testing). |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
It seems like io_uring doesn't always respect O_NONBLOCK flag on pipe file descriptors, regardless of whether IOSQE_ASYNC is used. I.e. I have been unable to consistently get submissions to write more than a full pipe of bytes when the reader is sluggish. The worker thread seems to be writing till the pipe is full (however many pages are free), then completing. If you just used a synchronous write() it typically blocks until all bytes are written or the pipe is closed. I've cleared any O_NONBLOCK flags on the fd and tried setting IOSQE_ASYNC. I have been working extensively with io_uring on some research for awhile now, but mostly on files so I just noticed this.
I think this could theoretically still be semantically correct according to Posix (https://pubs.opengroup.org/onlinepubs/9799919799/functions/write.html), but it makes for many more trips to user space and many more SQEs for large pipe writes.
Here's a test program, to illustrate, and an example execution on my machine:
Beta Was this translation helpful? Give feedback.
All reactions