PythonStudy - epoll module asynchronous IO model

IO model comparison module implemented and select

1.select, need to traverse the socket list, the waiting queue frequently add removal operations,

2. After data arrives also need to know what all the variables socket to socket data

Two operations consume time increases with the number to be monitored socket is greatly increased,

In consideration only specifies the maximum efficiency can only monitor the 1024 socket

epoll problem to be solved

1. avoid frequent operation of the queue

2. Avoid traverse all socket

For the first question

We look at the treatment of select

while True:
    r_list, w_list, x_list = select.select (RLIST, wlist, XList, 0.5) 
  # 0.5 here refers to select poll every 0.5 seconds corresponding socket has not ready

After each treatment once read, you need to repeat the punch used, including the removal process, adding process, the default process will be added to the waiting queue, and blocking the process of living, but the waiting queue update operation is not frequent ,

So the first question

epoll program is taken, it will queue the maintenance and blocked processes two operations split !!!

Related code is as follows

import socket,select
server = socket.socket()
server.bind(("127.0.0.1",1688))
server.listen(5)

# Create epoll event object, the follow-up to monitor the event to which the 
epoll = select.epoll ()
 # registration server listens fd to wait for read event collection 
epoll.register (server.fileno (), select.EPOLLIN)

# Wait for events 
the while True:
  for our sock, Event in epoll.poll ():
    Pass
```

# Epoll in the register and unregister function is used to maintain the waiting queue

# Epoll.poll is used to block the process

Such an action would avoid the need to re-treatment every operational problems waiting queue

For the second question

select the process can not know which socket is the data it needs to traverse

epol To solve this problem, maintain a ready list in the kernel,

1. Create an object epoll, epoll also corresponds to a file, the file system management

2. When execution register, add objects to epoll wait queue of socket

3. When data arrives, CPU executes an interrupt program, copy the data to a socket

4. In epoll, the interrupt program will be executed next epoll object callback function, passing Ready socket object

5. socket, ready to add to the list

6. Wake epoll queue of waiting processes

After the wake-up process, due to the ready list, so no need to traverse the socket, you can deal directly with the ready list

 

To solve these two problems, the amount of concurrency has been greatly improved, while maintaining the maximum level of thousands of socket

epoll correlation function

Import module select select Import

epoll = select.epoll () to create a epoll objects

epoll.register (file handle, event type) registered to monitor file handle and events

Event Type:

  select.EPOLLIN readable event

  select.EPOLLOUT can write event

  select.EPOLLERR error events

  select.EPOLLHUP client disconnection events

  epoll.unregister (file handle) destroyed the file handle

  epoll.poll (timeout) when a file handle changes will be in the form of a list of active reporting to the user process

  timeout to timeout, the default is -1, which waits until the file handle change, if you specify 1, then changes epoll report every 1 second of the current file handles, if no change is returned empty

  epoll.fileno () returns the file descriptor epoll control (Return the epoll control file descriptor)

  epoll.modfiy (fineno, event) fineno file descriptor for the event type of the event is to modify the action event corresponding to the file descriptor

  epoll.fromfd (fileno) to create an object from a specified epoll file descriptor

  epoll.close () to close the control object descriptor epoll

Case

Client code

# Coding: UTF-8 
# client 
# Create the client socket object 
Import socket
clientsocket = socket.socket, (socket.AF_INET,
socket.SOCK_STREAM)
#服务端IP地址和端口号元组
server_address = ('127.0.0.1',1688)
#客户端连接指定的IP地址和端口号
clientsocket.connect(server_address)

while True:
#输入数据
    data = raw_input('please input:')
    if data == "q":
        break
    if not data:
        continue
    #客户端发送数据
    clientsocket.send(data.encode("utf-8"))
    #客户端接收数据
    server_data = clientsocket.recv(1024)
    print ('客户端收到的数据:',server_data)
    #关闭客户端socket
clientsocket.close()
        

服务器代码

# coding:utf-8
import socket, select

server = socket.socket()
server.bind(("127.0.0.1", 1688))
server.listen(5)

msgs = []


fd_socket = {server.fileno(): server}
epoll = select.epoll()
# 注册服务器的 写就绪
epoll.register(server.fileno(), select.EPOLLIN)

while True:
    for fd, event in epoll.poll():
        sock = fd_socket[fd]
        print(fd, event)
        # 返回的是文件描述符 需要获取对应socket
        if sock == server:  # 如果是服务器 就接受请求
            client, addr = server.accept()
            # 注册客户端写就绪
            epoll.register(client.fileno(), select.EPOLLIN)
            # 添加对应关系
            fd_socket[client.fileno()] = client

        # 读就绪
        elif event == select.EPOLLIN:
            data = sock.recv(2018)
            if not data:
                # 注销事件
                epoll.unregister(fd)
                # 关闭socket
                sock.close()
                # 删除socket对应关系
                del fd_socket[fd]
                print(" somebody fuck out...")
                continue

            print(data.decode("utf-8"))
            # 读完数据 需要把数据发回去所以接下来更改为写就绪=事件
            epoll.modify(fd, select.EPOLLOUT)
            #记录数据
            msgs.append((sock,data.upper()))
        elif event == select.EPOLLOUT:
            for item in msgs[:]:
                if item[0] == sock:
                    sock.send(item[1])
                    msgs.remove(item)
            # 切换关注事件为写就绪
            epoll.modify(fd,select.EPOLLIN)

 

Guess you like

Origin www.cnblogs.com/tingguoguoyo/p/11005785.html