NIO model: Multiple channel -> one selector -> SelectionKey queue -> thread pool

  • Channel is similar to a abstraction of file descriptor. It is bi-directional, but can asyncly read and write buffer
    • SocketChannel is commonly used in TCP client
    • ServerSocketChannel in handling TCP request from outside
    • DatagramChannel to handle UDP client and server
  • One selector to monitor mutliple channels, and we check the selector directly
  • Buffer is commonly memory mapped so we don’t have to copy from kernel space to user space
  • SelectionKey class states
    • Connect – when a client attempts to connect to the server. Represented by SelectionKey.OP_CONNECT
    • Accept – when the server accepts a connection from a client. Represented by SelectionKey.OP_ACCEPT
    • Read – when the server is ready to read from the channel. Represented by SelectionKey.OP_READ
    • Write – when the server is ready to write to the channel. Represented by SelectionKey.OP_WRITE

NIO itself is a case of the reactor model: mutliple Client -> one accepter -> mulitple channel -> one reactor –> multiple servers

Select() copies request from user space to kernel space, and in kernel mode to test if each request is ready.

  • Blocks on no data
  • Similar to poll() requires user to iterate all channels once more after notifies some channels are ready.

In level-triggered epoll(), all threads will wake up and try accept() - but only one can get it!

Unlike select(), poll(), epoll’s fd shars between user state and kernel state - that copy is saved

  • Epoll returns only the request with data. It reorders fds, and put all fd with data to the front, and then return