IO Concurrency Model

IO Classification

IO Classification: Blocking IO, Non-Blocking IO, IO Multiplexing, Asynchronous IO, etc.

Blocking IO

1. Definition: Block if the execution condition is not satisfied when performing an IO operation.Blocking IO is the default form of IO.

2. Efficiency: Blocking IO is a very inefficient type of IO.But because of its simplicity, it is the default IO behavior.

3. Blockage:

  • Function blocking caused by an unsatisfactory execution condition
    e.g. accept input recv

  • Blocking state due to long IO processing time
    e.g. Network Transport, Large Files Read and Write

non-blocking IO

1. Definition: By modifying the IO property behavior, the originally blocked IO will become non-blocked.

Set socket to non-blocking IO

sockfd.setblocking(bool)

  • Function: Set socket to non-blocking IO
  • Parameters: The default is True, meaning socket IO is blocked; False makes socket IO non-blocked

Timeout detection: Set a maximum blocking time beyond which no blocking wait will occur.

sockfd.settimeout(sec)

  • Function: Set timeout for sockets
  • Parameter: Set time

IO Multiplex

1. Definition: Monitor multiple IO events simultaneously, when which IO event is ready to execute which IO event.This creates a behavior that can handle multiple IOs simultaneously, avoids one IO blocking causing other IOs to fail to execute, and improves the efficiency of IO execution.

2. Specific plan:

  • select method: windows linux unix
  • poll method: linux unix
  • epoll method: linux

select method

rs, ws, xs=select(rlist, wlist, xlist[, timeout])

  • Function: Monitor IO events, block waiting for IO to occur
  • Parameters:
    • The rlist list holds focused IO events waiting to occur
    • The wlist list holds the IO events of interest to be proactively processed
    • The xlist list list holds IO to handle for focused exceptions
    • Timeout timeout
  • Return value:
    • Ready IO in rs list rlist
    • Ready IO in ws list wlist
    • Ready IO in xs list xlist

select implements tcp service

1. Put IO of interest in the list of corresponding monitoring categories

2. Monitoring through the select function

3. Traverse through the list of returned select s to determine ready IO events

4. Handle IO events that occur

Be careful:

If there is an IO event in wlist, select immediately returns to ws

Do not have Dead Loop Occupying Server during IO Processing

IO multiplexing consumes less resources and is more efficient

 1 """
 2 Key Codes
 3 
 4 Idea analysis:
 5 1.Will Focus on IO Put in the list of corresponding monitoring categories
 6 2.adopt select Functions for monitoring
 7 3.ergodic select Return a list of values to make sure you're ready IO Event
 8 4.Handle Occurring IO Event
 9 """
10 
11 from socket import *
12 from select import select
13 
14 # Create a listening socket as a concernIO
15 s = socket()
16 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
17 s.bind(('0.0.0.0',8888))
18 s.listen(3)
19 
20 # Set up a list of concerns
21 rlist = [s]
22 wlist = []
23 xlist = [s]
24 
25 # Cycle MonitoringIO
26 while True:
27   rs,ws,xs = select(rlist,wlist,xlist)
28   # Traverse through three return lists,HandleIO
29   for r in rs:
30     # Based on traversal toIODifferent usesifCase-by-case processing
31     if r is s:
32       c,addr = r.accept()
33       print("Connect from",addr)
34       rlist.append(c) # Add NewIOEvent
35     # else Client Socket Ready
36     else:
37       data = r.recv(1024)
38       # Client Exit
39       if not data:
40         rlist.remove(r) # Remove from the list of concerns
41         r.close()
42         continue # Continue with other readinessIO
43       print("Receive:",data.decode())
44       # r.send(b'OK')
45       # We want to take the initiative in dealing with thisIOobject
46       wlist.append(r)
47 
48   for w in ws:
49     w.send(b'OK')
50     wlist.remove(w) # Remove after Using
51 
52   for x in xs:
53     pass
select tcp service model

Bit operation

Definition: Convert integers to binary, operate on binary bits

Operational Symbols:

poll method

p = select.poll()

p.register(fd,event)   

IO event Type event Event to Focus on

Common types:

  p.register(sockfd,POLLIN|POLLERR)

p.unregister(fd)

events = p.poll()

Evets format [(fileno,event), ()...

Each tuple is a ready IO, with the first being the fileno of the IO and the second being the IO ready event type

poll_server step:

  1. Create Socket
  2. register socket
  3. Create a lookup dictionary and maintain it
  4. Cyclic monitoring of IO occurrence
  5. Processing IO Occurred
 1 """
 2 Master as much as possible
 3 
 4 Idea analysis:
 5 1. Create sockets as monitoringIO
 6 2. Socket register
 7 3. Create a lookup dictionary and maintain it(Always registerIOBring into correspondence with)
 8 4. Cycle Monitoring IO Happen
 9 5. Handle Occurring IO
10 """
11 
12 from socket import *
13 from select import *
14 
15 # Create Socket
16 s = socket()
17 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
18 s.bind(('0.0.0.0',8888))
19 s.listen(3)
20 
21 # EstablishpollObject Attentions
22 p = poll()
23 
24 # Create a lookup dictionary for use withfilenolookupIOobject
25 fdmap = {s.fileno():s}
26 
27 # follows
28 p.register(s,POLLIN|POLLERR)
29 
30 # Cycle Monitoring
31 while True:
32   events = p.poll()
33   # Loop through events that occur fd-->fileno
34   for fd,event in events:
35     # Distinguish events for processing
36     if fd == s.fileno():
37       c,addr = fdmap[fd].accept()
38       print("Connect from",addr)
39       # Add new concernsIO
40       p.register(c,POLLIN|POLLERR)
41       fdmap[c.fileno()] = c # Maintain Dictionary
42     # Bitwise and Decision YesPOLLINBe ready
43     elif event & POLLIN:
44       data = fdmap[fd].recv(1024)
45       if not data:
46         p.unregister(fd) # Remove Attention
47         fdmap[fd].close()
48         del fdmap[fd]  # Remove from Dictionary
49         continue
50       print("Receive:",data.decode())
51       fdmap[fd].send(b'OK')
poll server program

epoll method

1. Usage: basically the same as poll

2.epoll features:

 1 """
 2 Master as much as possible
 3 """
 4 
 5 from socket import *
 6 from select import *
 7 
 8 # Create Socket
 9 s = socket()
10 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
11 s.bind(('0.0.0.0',8888))
12 s.listen(3)
13 
14 # Establish epollObject Attentions
15 ep = epoll()
16 
17 # Create a lookup dictionary for use withfilenolookupIOobject
18 fdmap = {s.fileno():s}
19 
20 # follows
21 ep.register(s,EPOLLIN|EPOLLERR)
22 
23 # Cycle Monitoring
24 while True:
25   events = ep.poll()
26   # Loop through events that occur fd-->fileno
27   for fd,event in events:
28     print("Honey, you haveIONeed to be handled")
29     # Distinguish events for processing
30     if fd == s.fileno():
31       c,addr = fdmap[fd].accept()
32       print("Connect from",addr)
33       # Add new concernsIO
34       # Change Trigger Mode to Edge Trigger
35       ep.register(c,EPOLLIN|EPOLLERR|EPOLLET)
36       fdmap[c.fileno()] = c # Maintain Dictionary
37     # Bitwise and Decision Yes EPOLLINBe ready
38     # elif event & EPOLLIN:
39     #   data = fdmap[fd].recv(1024)
40     #   if not data:
41     #     ep.unregister(fd) #Remove Attention
42     #     fdmap[fd].close()
43     #     del fdmap[fd]  #Remove from Dictionary
44     #     continue
45     #   print("Receive:",data.decode())
46     #   fdmap[fd].send(b'OK')
epoll server program

Keywords: C socket Linux iOS Unix

Added by mimcris on Wed, 19 Jun 2019 20:55:11 +0300