IO may be blocking/non-blocking and synchronous/asynchronous. POSIX API provides synchronous blocking API (e.g. classic read, write, send, recv calls), synchronous non-blocking API (same functions, file descriptors opened with O_NONBLOCK
flag and IO-multiplexing calls) and asynchonous API (functions starting with aio_
).
Synchronous API is usually used with "one thread/process per fd" style. This is dreadful for resources. Non-blocking API allows to operate with a set of fds in one thread.