The difference between horizontal departure and edge departure

Source: Internet
Author: User
Tags epoll

There are horizontal triggers in the IO multiplexing of Linux, and the edge triggers two modes, the difference between the two modes is as follows:

Horizontal trigger: A notification is triggered if the file descriptor is ready to perform IO operations that are non-blocking. Allows the state of the IO to be repeatedly detected at any time, and it is not necessary to perform as many io.select,poll as possible after each descriptor is in the horizontal trigger.

Edge Trigger: A notification is triggered if a file descriptor has a new IO activity since the last state change. To perform as many IO operations as possible after receiving an IO event notification, Because if you do not complete IO in one notification, you will need to wait until the next new IO activity arrives to get the ready descriptor. The signal-driven IO is an edge trigger.

The epoll can be triggered either horizontally or by edge.

You may not be fully aware of the differences between the two models, we can illustrate: a pipeline received 1kb of data, Epoll will immediately return, this time read 512 bytes of data, and then call Epoll again. If it is triggered horizontally, Epoll will return immediately, Because there is data ready. If the edge trigger does not return immediately, because the data is readable but has triggered a notification, there is no new data to arrive at this time, until new data arrives Epoll will return, when the old data and new data can be read to ( Of course it is necessary for you to read as much as possible this time).

Here we also explain from an electronic point of view:

Horizontal trigger: The notification is triggered only when the high level (1) or low (0) is activated, as long as the two States are notified. As long as there is data readable (descriptor ready), the horizontally triggered epoll returns immediately.

Edge triggering: Notifications are triggered only when the level changes (high to low, or low to high). The above mentioned that even if there is data to be readable, but no new IO activity arrives, Epoll will not return immediately.

Edge Trigger (edge-triggered) ET: an event is triggered whenever the state changes.

"to read the socket example, assume that after a long period of silence, there are now 100 bytes, and both the edge trigger and the conditional trigger will produce a read Ready notification notification application. The application reads 50 bytes and then calls the API again to wait for the IO event. At this point the horizontally triggered API will return the user immediately to a read ready notification because there are still 50 bytes of readable. The edge-triggered API is stuck for long waits because the readable state does not change. So when using edge-triggered APIs, be aware that each time you read the socket back to ewouldblock, otherwise the socket is obsolete. When using the conditional-triggered API, do not focus on the socket writable event if the application does not need to write, or it will return a write ready notification an unlimited number of times. Everyone commonly used Select is the level trigger this category, long-term concern socket write event will appear CPU 100% problem.


  1. /*************************************************************************
  2. > File name:t_select.c
  3. > Author:liuxingen
  4. > Mail: [email protected]
  5. > Created time:2014 August 11 Monday 21:22 32 seconds
  6. ************************************************************************/
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <sys/types.h>
  10. #include <sys/time.h>
  11. #include <sys/select.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. int Main (int argc, char *argv[])
  15. {
  16. struct Timeval timeout;
  17. Char buf[10];
  18. Fd_set Readfds;
  19. int nread, Nfds, ready, FD;
  20. while (1)
  21. {
  22. Timeout.tv_sec = 20L;
  23. timeout.tv_usec = 0;
  24. FD = 0; Stdin
  25. Nfds = fd + 1;
  26. Fd_zero (&readfds);
  27. Fd_set (FD, &readfds);
  28. Ready = Select (Nfds, &readfds, NULL, NULL, &timeout);
  29. if (ready = =-1 && errno = = eintr)
  30. {
  31. Continue
  32. }else if (ready = =-1)
  33. {
  34. fprintf (stderr, "select Error:%s\n", Strerror (errno));
  35. }
  36. for (fd = 0; fd < Nfds; fd++)
  37. {
  38. if (Fd_isset (FD, &readfds))
  39. {
  40. Nread = Read (FD, buf, 9);
  41. Buf[nread] = ' + ';
  42. Puts (BUF);
  43. }
  44. }
  45. }
  46. return 0;
  47. }
The above example reads up to 9 bytes at a time, and when we enter 20 bytes at a time and then three calls to select, the data is immediately read every time, which proves that the select will return as soon as the data is ready in the horizontal trigger.

[Plain]View Plaincopy
    1. [Email protected]:~/station$./t_select
    2. Ni hao ma, wo hen hao A, ni ne???
    3. Ni hao Ma
    4. , Wo Hen
    5. Hao A, ni
    6. Ne???
    7. ^c

[CPP]View Plaincopy
  1. /*************************************************************************
  2. > File name:demo_sigio.c
  3. > Author:liuxingen
  4. > Mail: [email protected]
  5. > Created time:2014 August 14 Thursday 21:32 03 seconds
  6. ************************************************************************/
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #include <ctype.h>
  12. #include <signal.h>
  13. #include <fcntl.h>
  14. static int g_fd;
  15. static void Sigio_handler (int signum)
  16. {
  17. char buf[8] = {0};
  18. if (read (G_FD, buf, 7) < 0)
  19. {
  20. fprintf (stderr, "read error:%s\n", Strerror (errno));
  21. }else
  22. {
  23. printf ("Sigio recv:%s\n", buf);
  24. }
  25. }
  26. int Main (int argc, char *argv[])
  27. {
  28. struct Sigaction Act;
  29. int flags, i = 1, fds[2];
  30. pid_t pid;
  31. if (pipe (FDS) < 0)
  32. {
  33. fprintf (stderr, "Pipe error:%s\n", strerror (errno));
  34. return 1;
  35. }
  36. if ((PID = fork ()) > 0)
  37. {
  38. Close (fds[1]);
  39. Dup2 (Fds[0], g_fd);
  40. Sigemptyset (&act.sa_mask);
  41. Act.sa_flags = Sa_restart;
  42. Act.sa_handler = Sigio_handler;
  43. if (Sigaction (SIGIO, &act, NULL) = =-1)
  44. {
  45. fprintf (stderr, "Sigaction error:%s\n", Strerror (errno));
  46. return 1;
  47. }
  48. if (Fcntl (G_FD, F_setown, getpid ()) = =-1)
  49. {
  50. fprintf (stderr, "Fcntl f_setown error:%s\n", Strerror (errno));
  51. return 1;
  52. }
  53. Flags = FCNTL (G_FD, F_GETFL);
  54. if (Fcntl (G_FD, F_SETFL, Flags | O_async | O_nonblock) = =-1)
  55. {
  56. fprintf (stderr, "Fcntl f_getfl error:%s\n", Strerror (errno));
  57. return 1;
  58. }
  59. while (1)
  60. {
  61. Sleep (10);
  62. }
  63. }else
  64. {
  65. char buf[20] = {0};
  66. Close (Fds[0]);
  67. for (i = 0; i < 3; i++)
  68. {
  69. snprintf (BUF, "This is loop%d", i);
  70. Write (Fds[1], buf, strlen (BUF));
  71. printf ("Loop%d\n", i);
  72. Sleep (3);
  73. }
  74. }
  75. return 0;
  76. }

Because the signal-driven IO is an edge trigger, the above is an example of a signal driver. From the output below you can tell: we write 14 bytes at a time, but we only read 7 bytes at a time, unless we wait until the next data write and no longer trigger the sigio signal. And the last unread data will continue to be read the next time.

[Plain]View Plaincopy
    1. [Email protected]:~/station$./demo_sigio
    2. Loop 0
    3. Sigio Recv:this is
    4. Loop 1
    5. Sigio Recv:loop 0
    6. Loop 2
    7. Sigio Recv:this is
    8. Sigio Recv:loop 1
    9. ^c

The difference between horizontal departure and edge departure

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.