4 ms·
It's also worth noting that the Windows IOCP model unifies network and other I/O. This allows something like a Web server to do asynchronous reads and writes o
by YZF 10y ago
It's also worth noting that the Windows IOCP model unifies network and other I/O. This allows something like a Web server to do asynchronous reads and writes on files without needing more threads and still also servicing the network. Would be nice to get similar capabilities in Linux.
EDIT: Also IIRC when using select() writes can still block your thread...
- snnn 10y agoAnd also user defined events and timers(through the new thread pool API)
- hendzen 10y agoThis is all possible on Linux today with timerfd [0] and eventfd [1]. You can use the same mechanism for async file-IO with libaio and the IOCB_FLAG_RESFD [2] flag. Granted libaio only really works well on XFS [3], and even there it has issues. [0] - https://lwn.net/Articles/251413/ https://lwn.net/Articles/251413/ [1] - http://man7.org/linux/man-pages/man2/eventfd.2.html http://man7.org/linux/man-pages/man2/eventfd.2.html [2] - https://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt https://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt [3] - http://www.scylladb.com/2016/02/09/qualifying-filesystems/ http://www.scylladb.com/2016/02/09/qualifying-filesystems/
- psykotic 10y ago> EDIT: Also IIRC when using select() writes can still block your thread... You should only ever use select() with file descriptors in non-blocking mode. Otherwise there's an inherent race condition with any readiness signaling mechanism along these lines. But yes, the read/write syscalls are not asynchronous, and select() on regular files are required by POSIX to always be signaled as ready for reading and writing. Basically, descriptor readiness as per select() does not mean and has never meant that the thread won't be temporarily descheduled and put on an IO wait queue. Its semantics are only a useful fit for things like UARTs, sockets, pipes, etc. By the way, even with asynchronous/overlapped IO on Windows, there are cases where asynchronous reads/writes on files will effectively be synchronous, especially in the common case of file-extending writes. See https://support.microsoft.com/en-us/kb/156932 https://support.microsoft.com/en-us/kb/156932 for details. The only work-around I know of is to use SetFileValidData to pre-extend the file, but that requires increased privileges and so is not often feasible (and usually not worth it compared to queuing the writes to a dedicated IO thread).
- zrm 10y agoThe difficult thing with IOCP is that it requires architectural changes to the application and there are platforms that have no reasonable equivalent to it. So portable applications that use IOCP semantics are hard to support on those platforms. Whereas essentially all platforms (including Windows) have select() and most have something equivalent but better like epoll() or kqueue(). And for most applications the benefits of IOCP over epoll() or kqueue() are only theoretical. A call to send() or recv() isn't literally synchronous, it's buffered by the OS. So using IOCP looks better on paper than in practice.
- TwoBit 10y agoFor many use cases, either of the two can be written as an emulation over the other.
- zrm 10y ago> For many use cases, either of the two can be written as an emulation over the other. Between select/poll/epoll/kqueue/etc and each other that is easy. You have a few functions like "register(ctx, fd, event)" and "wait_for_events(ctx)" that map straight to each of the implementations. To use IOCP it's not just those you have to wrap. It's also send(), sendto(), sendmsg(), write(), recv(), recvfrom(), recvmsg(), read(), connect(), accept() and others. In ways that don't make for trivial or efficient implementations. And then contend with any third party library that uses any of those internally. There is a reason libev doesn't support IOCP and libevent only supports it by exposing a different API on Windows.
- JdeBP 10y agoThe devil is in the details. Consider Mark Heily's libkqueue library for Linux that emulates kqueue/kevent. Because of the way that signalfd, upon which it is built, works, code that uses kevent with signals on the BSDs has to be written one way and on Linux has to be written another. It's a subtle difference in the manual page; and it's all too easy to read the wrong implementation's manual page on the WWW (if one makes the mistake of using a search engine to find manual pages) and write things incorrectly. It is also telling, of how difficult to interconvert it actually is in practice, that the Heily libkqueue does not implement EVFILT_AIO, EVFILT_FS, or EVFILT_PROCDESC, and implements some of the others in only a limited fashion.
- makomk 10y agoAs I understand it, the Windows caching layer doesn't actually support asynchronous IO. Any asynchronous cached file IO runs on a small, fixed-size system-wide thread pool using blocking IO, and once that runs out all such operations block until completion. That's why Windows software generally uses its own thread pools for file IO.