## 二、I/O 复用
@@ -138,17 +138,21 @@ tv.tv_usec = 0;
int ret = select( largest_sock + 1, &fd_in, &fd_out, NULL, &tv );
// Check if select actually succeed
-if ( ret == -1 )
+if ( ret == -1 ) {
// report error and abort
-else if ( ret == 0 )
+}
+else if ( ret == 0 ) {
// timeout; no event detected
+}
else
{
- if ( FD_ISSET( sock1, &fd_in ) )
+ if ( FD_ISSET( sock1, &fd_in ) ) {
// input event on sock1
+ }
- if ( FD_ISSET( sock2, &fd_out ) )
+ if ( FD_ISSET( sock2, &fd_out ) ) {
// output event on sock2
+ }
}
```
@@ -184,12 +188,14 @@ fds[1].fd = sock2;
fds[1].events = POLLOUT;
// Wait 10 seconds
-int ret = poll( &fds, 2, 10000 );
+int ret = poll( fds, 2, 10000 );
// Check if poll actually succeed
-if ( ret == -1 )
+if ( ret == -1 ) {
// report error and abort
-else if ( ret == 0 )
+}
+else if ( ret == 0 ) {
// timeout; no event detected
+}
else
{
// If we detect the event, zero it out so we can reuse the structure
@@ -234,7 +240,7 @@ epoll_ctl() 用于向内核注册新的描述符或者是改变某个文件描
从上面的描述可以看出,epoll 只需要将描述符从进程缓冲区向内核缓冲区拷贝一次,并且进程不需要通过轮询来获得事件完成的描述符。
-
+
epoll 仅适用于 Linux OS。
@@ -247,8 +253,9 @@ epoll 对多线程编程更加友好,一个线程调用了 epoll_wait() 另一
// The function argument is ignored (it was not before, but now it is), so put your favorite number here
int pollingfd = epoll_create( 0xCAFE );
-if ( pollingfd < 0 )
- // report error
+if ( pollingfd < 0 ) {
+ // report error
+}
// Initialize the epoll structure in case more members are added in future
struct epoll_event ev = { 0 };
@@ -261,8 +268,9 @@ ev.data.ptr = pConnection1;
ev.events = EPOLLIN | EPOLLONESHOT;
// Add the descriptor into the monitoring list. We can do it even if another thread is
// waiting in epoll_wait - the descriptor will be properly added
-if ( epoll_ctl( epollfd, EPOLL_CTL_ADD, pConnection1->getSocket(), &ev ) != 0 )
+if ( epoll_ctl( pollingfd, EPOLL_CTL_ADD, pConnection1->getSocket(), &ev ) != 0 ) {
// report error
+}
// Wait for up to 20 events (assuming we have added maybe 200 sockets before that it may happen)
struct epoll_event pevents[ 20 ];
@@ -270,10 +278,12 @@ struct epoll_event pevents[ 20 ];
// Wait for 10 seconds, and retrieve less than 20 epoll_event and store them into epoll_event array
int ready = epoll_wait( pollingfd, pevents, 20, 10000 );
// Check if epoll actually succeed
-if ( ret == -1 )
+if ( ready == -1 ) {
// report error and abort
-else if ( ret == 0 )
+}
+else if ( ready == 0 ) {
// timeout; no event detected
+}
else
{
// Check if any events detected
@@ -337,3 +347,4 @@ poll 没有最大描述符数量的限制,如果平台支持并且对实时性
- [poll vs select vs event-based](https://daniel.haxx.se/docs/poll-vs-select.html)
- [select / poll / epoll: practical difference for system architects](http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/)
- [Browse the source code of userspace/glibc/sysdeps/unix/sysv/linux/ online](https://code.woboq.org/userspace/glibc/sysdeps/unix/sysv/linux/)
+- [epoll(7) — Linux manual page](https://man7.org/linux/man-pages/man7/epoll.7.html)
diff --git a/notes/pics/io-async.png b/notes/pics/io-async.png
new file mode 100644
index 00000000..728ab3a7
Binary files /dev/null and b/notes/pics/io-async.png differ
diff --git a/notes/pics/io-blocking.png b/notes/pics/io-blocking.png
new file mode 100644
index 00000000..d2d0f503
Binary files /dev/null and b/notes/pics/io-blocking.png differ
diff --git a/notes/pics/io-compare.png b/notes/pics/io-compare.png
new file mode 100644
index 00000000..470432bc
Binary files /dev/null and b/notes/pics/io-compare.png differ
diff --git a/notes/pics/io-multiplex.png b/notes/pics/io-multiplex.png
new file mode 100644
index 00000000..f00a310b
Binary files /dev/null and b/notes/pics/io-multiplex.png differ
diff --git a/notes/pics/io-nonblocking.png b/notes/pics/io-nonblocking.png
new file mode 100644
index 00000000..1c65449e
Binary files /dev/null and b/notes/pics/io-nonblocking.png differ
diff --git a/notes/pics/io-signal.png b/notes/pics/io-signal.png
new file mode 100644
index 00000000..b700a40b
Binary files /dev/null and b/notes/pics/io-signal.png differ
diff --git a/tools/diagram/src/io-async.svg b/tools/diagram/src/io-async.svg
new file mode 100644
index 00000000..a2b50970
--- /dev/null
+++ b/tools/diagram/src/io-async.svg
@@ -0,0 +1,55 @@
+
diff --git a/tools/diagram/src/io-blocking.svg b/tools/diagram/src/io-blocking.svg
new file mode 100644
index 00000000..7233fcea
--- /dev/null
+++ b/tools/diagram/src/io-blocking.svg
@@ -0,0 +1,53 @@
+
diff --git a/tools/diagram/src/io-compare.svg b/tools/diagram/src/io-compare.svg
new file mode 100644
index 00000000..c477b96b
--- /dev/null
+++ b/tools/diagram/src/io-compare.svg
@@ -0,0 +1,66 @@
+
diff --git a/tools/diagram/src/io-multiplex.svg b/tools/diagram/src/io-multiplex.svg
new file mode 100644
index 00000000..962b47f5
--- /dev/null
+++ b/tools/diagram/src/io-multiplex.svg
@@ -0,0 +1,59 @@
+
diff --git a/tools/diagram/src/io-nonblocking.svg b/tools/diagram/src/io-nonblocking.svg
new file mode 100644
index 00000000..7d9b9a53
--- /dev/null
+++ b/tools/diagram/src/io-nonblocking.svg
@@ -0,0 +1,63 @@
+
diff --git a/tools/diagram/src/io-signal.svg b/tools/diagram/src/io-signal.svg
new file mode 100644
index 00000000..4f989282
--- /dev/null
+++ b/tools/diagram/src/io-signal.svg
@@ -0,0 +1,61 @@
+