IO multi-channel model -- select, IO model -- select

Source: Internet
Author: User

IO multi-channel model -- select, IO model -- select
1. Trigger of IO multiplexing Model

First, we will introduce the concept of "Trigger" in an I/O multi-channel model:

1 # There are two modes of horizontal triggering and edge triggering in linux I/O multiplexing: 2 #3 # horizontal triggering: if the file descriptor is ready for non-blocking IO operations, a notification is triggered. allows you to repeatedly check the IO status at any time. 4 # There is no need to execute as many IO operations as possible after each descriptor is ready. select and poll are horizontally triggered. 5 #6 # edge triggering: if a new IO activity comes after the last state change of the file descriptor, a notification is triggered. after receiving an IO Event Notification, perform as many I/O operations as possible 7, because if I/O is not completed in a notification, you need to wait until the next new IO activity arrives to get the ready description 8. signal-driven IO is edge-triggered. 9 #10 # epoll can be either horizontally triggered or edge triggered. 11 #12 # You may not be fully aware of the differences between the two modes. For example, if an MPS queue receives 1 kb of data, epoll will return immediately, at this time, 13 # reads 512 bytes of data and calls epoll again. in this case, if it is triggered horizontally, epoll will return immediately because the data is ready. if it is triggered by edge 14 #, it will not be returned immediately, because although there is data readable, a notification has been triggered, and no new data has been sent to this notification, 15 # epoll will not return until new data arrives. At this time, the old data and new data can be read (of course, you need to read as much as possible this time ). 16 17 18 # below we also explain from the electronic point of view: 19 #20 # horizontal triggering: that is, the notification is triggered only when the high level (1) or low level (0, you only need to be notified in these two statuses. as long as 21 # is readable (descriptor ready), epoll triggered horizontally is returned immediately. 22 #23 # edge trigger: the notification is triggered only when the level changes (from high to low, or from low to high. the epoll will not return immediately even if the data is 24 # readable but there is no new IO activity. 25 26 horizontal trigger and edge trigger
2. Detailed code analysis
# Server
1 import socket 2 import select 3 4 sk1 = socket. socket (socket. AF_INET, socket. SOCK_STREAM) 5 sk1.bind ("127.0.0.1", 6667) 6 sk1.listen (5) 7 8 sk2 = socket. socket (socket. AF_INET, socket. SOCK_STREAM) 9 sk2.bind ("127.0.0.1", 6668) 10 sk2.listen (5) 11 while True: 12 r, w, e = select. select ([sk1, sk2], [], []) 13 for I in r: 14 conn, addr = I. accept () 15 print (conn) 16 print ("hello") 17 print (">>>", r)
1 # client 2 import socket 3 import time 4 5 sk = socket. socket (socket. AF_INET, socket. SOCK_STREAM) 6 while True: 7 sk. connect ("127.0.0.1", 6667) 8 print ("hello") 9 sk. sendall (bytes ("byebye", encoding = "UTF-8") 10 time. sleep (2) 11 break

The above code is very simple. You can see the output at a Glance:

<Socket. socket fd = 5, family = AddressFamily. AF_INET, type = SocketKind. SOCK_STREAM, proto = 0, laddr = ('2017. 0.0.1 ', 6667), raddr = ('2017. 0.0.1 ', 49322)>
Hello
>>> [<Socket. socket fd = 3, family = AddressFamily. AF_INET, type = SocketKind. SOCK_STREAM, proto = 0, laddr = ('2017. 0.0.1 ', 6667)>]

But what I want to know is, if you change the server code to the following (comment out the two lines of code below the for loop ):

 1 import socket 2 import select 3  4 sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 5 sk1.bind(("127.0.0.1", 6667)) 6 sk1.listen(5) 7  8 sk2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 9 sk2.bind(("127.0.0.1", 6668))10 sk2.listen(5)11 while True:12     r, w, e = select.select([sk1, sk2], [], [])13     for i in r:14         # conn, addr = i.accept()15         # print(conn)16         print("hello")17     print(">>>", r)

So what will the output result be after the re-run?

The server will always print the following information:

Hello
>>> [<Socket. socket fd = 3, family = AddressFamily. AF_INET, type = SocketKind. SOCK_STREAM, proto = 0, laddr = ('2017. 0.0.1 ', 6667)>]

As for the reason, I think you can give an explanation based on the first part.

Since select works in the form of "Horizontal triggering", before the two lines of code are commented out,

conn, addr = i.accept()print(conn)

These two lines of code (as long as it is the first line) are equivalent to using the elements in r (r, w, and e are three lists), so after use, "Horizontal triggering" will not remind (return) new elements. If no new connection comes after use, it will be blocked here

r, w, e = select.select([sk1, sk2], [], [])

So it will only be printed once. If I re-run the client at this time, the new connection will arrive, and the server will print the following new information.

<Socket. socket fd = 5, family = AddressFamily. AF_INET, type = SocketKind. SOCK_STREAM, proto = 0, laddr = ('2017. 0.0.1 ', 6667), raddr = ('2017. 0.0.1 ', 49372)>
Hello
>>> [<Socket. socket fd = 3, family = AddressFamily. AF_INET, type = SocketKind. SOCK_STREAM, proto = 0, laddr = ('2017. 0.0.1 ', 6667)>]

Next we will comment out the two lines of code:

Because the two lines of code are commented out, the elements in list r are not used. In the "Horizontal trigger" mode, the system will keep reminding you.

r, w, e = select.select([sk1, sk2], [], [])

This line of code will return a value, that is, it is not blocked, so "hello" will be printed in the for loop, in

print(">>>", r)

The server socket object will be printed all the time.

 

In other words: epoll supports two modes: horizontal triggering and edge triggering.

 

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.