Some forms
- Process
- Expensive to create and maintain
- Usally the number of processes is small and pooled
- Polling
- Available in traditional Unix and Windows
- Waster CPU time polling repeatedly when there is nothing else for the issuing process to do
- Essentially single-threaded, so may be unable to exploit I/O parallelism the hardware is capable of
- Select(/poll) loops
- Available in BSD Unix, and almost TCP/IP protocol stack
- Is a variation of polling
- A select loop uses the
select
system call tosleep
until a condition occurs on afile descriptor
- Reliable and relatively efficient, depends haveily on the Unix paradigm tha “everything is a file”
select
system call allow tuning of the acceptable event set
- Signals
- Essentially interrupts
- Available in BSD and POSIX Unix
- The main flow of the process could have been interruptted at nearly any point, resulting in inconsistent data structures as seen by the signal handler
- The signal handler is usually not able to issue further asynchronous I/O by itself
- Every blocking system call is potentially interruptible
- The programmer must usually incoroprate retry code at each call
- Callback functions
- Available in classic Mac OS, MVS and Windows
- Bear many of the characteristics of the signal method
- Each I/O request usually can have its own completion function, whereas the signal system has a single callback
- Stack depth can grow unmanageably
- Light-weight processes(LWPs) or threads
- Available in more modern Unixes
- Like the process, but without the data isolation
- Introduce its own problems, requrie kernel-provided synchronizaion mechanisms and thread-safe libraries
- Each LWP use traditional blocking synchronous I/O
- Completion queues/ports
- Available in Microsoft Windows, Solaris, AmigaOS, and DNIX
- I/O requests are issued asynchronously, but notifications of completion are provided via a synchronizing queue mechanism in the order they are completed
- Event flags
- It is essentially a completion queue of depth one
- To simulate the effect of queue ‘depth’, an additional event flag is required for each potential unprocessed (but completed) event, or event information can be lost.
- Channel I/O
- Available in mainframes(大型机) by IBM, Groupe Bull, and Unisys
- Channel I/O is designed to maximize CPU utilization and throughput by offloading most I/O onto a coprocessor(协处理器)
- The coprocessor has onboard DMA, handles device interrupts, is controlled by main CPU, and only interrupts main CPU when it’s truly necessary.
- Registered I/O
- Available in Windows Server 2012 and Windows 8
The vast majority of general-purpose computing hardware relies entirely upon two methods of implementing asynchronous I/O: polling and interrupts.
Usually both methods are used together, the balance depends heavily upon the design of the hardware and its required performance characteristics.
- Pure polling systems are entirely possible, small microcontrollers are often built this way.
- Most general-purpose computing systems rely heavily upon interrupts.
- Hybrid approaches are also possible, wherein an interrupt can trigger the beginning of some burst of asynchronous I/O, and polling is used within the burst itself.
C10K problem 翻译文章句子节选
一个线程服务多个客户端,并使用非阻塞I/O和电平触发的就绪通知
在Linux上/dev/poll有很多种实现,但是没有一种性能与epoll一样好,这些实现从来没有真正完整过。在linux上/dev/poll是不建议的。
一个线程服务多个客户端,并使用非阻塞 I/O 和变更就绪通知
“边缘触发”是“水平触发”就绪通知的对立面。这对编程错误有点不宽容,因为如果你错过了唯一的事件,连接事件就将永远的卡住。
一个服务器线程处理多个客户端请求,并使用异步I/O
一个服务器线程服务一个客户端,使用阻塞I/O
这样不好的地方在于需要为每个客户端使用一个完整的栈,从而比较浪费内存。
你可以减小每个线程所拥有的栈内存大小,但是由于大部分线程库在一旦线程创建后就不能增大线程栈大小,所以这样做就意味着你必须使你的程序最小程度地使用内存。
1:1 线程 vs M:N 线程
从某个角度来说, M:N被认为拥有更好的性能,但是由于很难被正确的编写,所以大部分人都远离了该方法。