-
Notifications
You must be signed in to change notification settings - Fork 0
/
OS_Event_Loop_Workings.txt
72 lines (43 loc) · 5.23 KB
/
OS_Event_Loop_Workings.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Non-Blocking mode makes it possible for a thread to read or write without blocking.
Non-Blocking mode doesn't let an application determine if it can perform an operation such system calls acccept(), read(), write etc without actually performing the operation.
E.g - If the non-blocking read operation succeeds, there are two important events
a. Aplication learns the read operation is possible.
b. Application also has read data that must be managed.
This duality prevents seperating the code that checks from stream readiness (First event) from the actual data procesing code without making the code significantly complicated.
Result - Non-Blocking mode is the foundation for readiness selection (select() system call) which offloads to the Operating System the work involved in checking for I/O stream readiness to perform read, write and other operations which was mentioned as first event without actually performing the operations.
E.g - If the non-blocking read operation succeeds, there are two important events with readiness selection
a. Application learns the read operation is possible no longer true and offloaded to the OS to determine if the operation is possible.
b. Application has read data that must be managed after stream readiness notifies the operation is possible.
The duality is no longer valid due to readiness selection implemented in the OS Kernel.
OS is instructed to observe a group of streams and return some indication of which streams are ready to perform a specific operation such as read or operation such as read and write. This capability lets a thread multiplex large number of active streams by using readiness information provided by the operating system.
Selector - is an object that maintains a set of channels that it examines to determine which channels are ready for reading, writing however the actual work is delegated to system call.
The ability to check a channel for readiness without having to wait when something isn't ready such as bytes are unavailable for reading and without also having to perform the operation while checking is the key to scalability. A single thread can manage a huge number of channels.
The following APIs
1. select(2)
2. poll(2)
3. epoll(7)
are asynchronous blocking I/O - Why ? Issues system call and returns immediately but they actually block in nature because the thread must check for I/O completion for example using poll(2) with read(2) operation.
EVERYTHING DISCUSSED ABOVE IS NON-BLOCKING SYNCHRONOUS I/O.
https://man7.org/linux/man-pages/man7/sigevent.7.html handles AIO (Asynchronous I/O)
It is bad to poll the OS for each IO in progress but instead all the IOs to determine which one is ready.All the above system calls, when the IO is ready the user must then call a read or write to tranfer data.
AIO is similar to epoll in that the OS is instructed to observe and manage to return indication which streams are ready but the major difference is that after poll or epoll informs the user that the resource is ready, the user must then read or write the resource.AIO handles differently in that it informs the user that IO is complete which infers the data or operation has already been complete or read into user's memory.
Readiness Notification Models
1. Level-Triggered notification: A fd is considered to be ready when it is possible to perform an I/O system call without blocking.
2. Edge-Triggered notification: Notification is provided if there is I/O activity on the fd since it was last monitored.
select(), poll() - Level-triggered ? Y, Edge Triggered ? N
signal driven I/O (AIO) - Level-triggered ? N, Edge Triggered ? Y
epoll() - Level-triggered ? Y, Edge Triggered ? Y (Either but not both)
None of these mechanism actually perform I/O. Instead, once we have determined that a file descriptor is ready, we use the
traditional I/O system calls to perform I/O
abstract int - select() - Selects a set of keys whose corresponding channels are ready for I/O operations.
-> Kernel behavior is to set the timeout value as -1, block until an event occurs or block indefinitely.
abstract int - select(long timeout) - Selects a set of keys whose corresponding channels are ready for I/O operations.
-> Kernel behavior is to set the value as timeout, block for up to timeout milliseconds until an event occurs or return.
abstract int - selectNow() - Selects a set of keys whose corresponding channels are ready for I/O operations.
-> Kernel behavior is set the timeout value as 0, perform a non-blocking behavior to see which events are currently available
on the fds.
----------------------------------------------------------------------
https://stackoverflow.com/questions/22177722/java-nio-non-blocking-channels-vs-asynchronouschannels
There's your misapprehension, right there. Non-blocking mode is different from asynchronous mode.
A non-blocking operation either transfers data or it doesn't. In either case there is no blocking, and the operation is complete once it returns. This mode is supported by SocketChannel, DatagramSocketChannel, and Selector.
An asynchronous operation starts when you call the method and continues in the background, with the result becoming available at a later time via a callback or a Future. This mode is supported by the AsynchronousSocketChannel etc classes you mention in your question.