Example of the select module in python

Source: Internet
Author: User
Tags error status code
The select module in Python focuses on IO multiplexing and provides three selectpollepoll methods (the last two are available in Linux, and windows only supports select ), in addition, the select module in Python focuses on I/O multiplexing and provides three select poll epoll methods (the last two are available in Linux, and windows only supports select ), the kqueue method (freeBSD system) is also provided)
Select method

The process specifies which file descriptors the kernel listens for (a maximum of 1024 fd events). when no file descriptor event occurs, the process is blocked; when one or more file descriptor events occur, the process is awakened.

When we call select:

1. switch context to kernel state

2. copy fd from user space to kernel space

3. the kernel traverses all fd and checks whether the corresponding event has occurred.

4. if the process does not occur, it will block the process. when the device driver is interrupted or has a timeout time, it will wake up the process and traverse it again.

5. return the fd after traversal.

6. copy fd from kernel space to user space

Fd: file descriptor

Fd_r_list, fd_w_list, fd_e_list = select. select (rlist, wlist, xlist, [timeout])

Parameter: four parameters are acceptable (the first three parameters are required)

Rlist: wait until ready for reading

Wlist: wait until ready for writing

Xlist: wait for an "exceptional condition"

Timeout: timeout

Returned value: three lists

The select method is used to monitor file descriptors (when the file descriptor condition is not met, select will block). when the state of a file descriptor changes, three lists will be returned.

1. when fd in the sequence of parameter 1 meets the "readable" condition, the changed fd is obtained and added to fd_r_list.

2. when parameter 2 contains fd, add all fd in this sequence to fd_w_list.

3. when fd in parameter 3 is incorrect, add the fd with the error to fd_e_list.

4. when the timeout time is null, the select statement will be blocked until the listening handle changes.

When the timeout time is n (positive integer), if the listening handle does not change, select will block n seconds, and then return three empty lists. if the listening handle changes, then run the command directly.


Instance:

Use select to implement a concurrent server

import socketimport select s = socket.socket()s.bind(('127.0.0.1',8888))s.listen(5)r_list = [s,]num = 0while True: rl, wl, error = select.select(r_list,[],[],10) num+=1 print('counts is %s'%num) print("rl's length is %s"%len(rl)) for fd in rl:  if fd == s:   conn, addr = fd.accept()   r_list.append(conn)   msg = conn.recv(200)   conn.sendall(('first----%s'%conn.fileno()).encode())  else:   try:    msg = fd.recv(200)    fd.sendall('second'.encode())   except ConnectionAbortedError:    r_list.remove(fd) s.close()


import socket flag = 1s = socket.socket()s.connect(('127.0.0.1',8888))while flag: input_msg = input('input>>>') if input_msg == '0':  break s.sendall(input_msg.encode()) msg = s.recv(1024) print(msg.decode()) s.close()

On the server side, we can see that we need to constantly call select, which means:

1. when there are too many file descriptors, it will be time-consuming to copy the file descriptors in the user space and kernel space.

2 when there are too many file descriptors, it is a waste of time for the kernel to traverse the file descriptors.

3 select supports up to 1024 file descriptors

Poll is not much different from select.

Epoll method:

Epoll improves select:

1. the epoll solution is in the epoll_ctl function. Every time a new event is registered to the epoll handle, all fd copies will be made to the kernel, instead of copying it repeatedly during epoll_wait. Epoll ensures that each fd is copied only once throughout the process.

2. epoll traverses the specified fd in epoll_ctl (this is required) and specifies a callback function for each fd. when the device is ready, this callback function is called when the waiting person on the queue is awakened, and this callback function adds the ready fd to a ready linked list. Epoll_wait is actually used to check whether there is a ready fd in this ready linked list.

3. epoll has no additional restrictions on file descriptors.


Select. epoll (sizehint =-1, flags = 0) create an epoll object

Epoll. close ()

Close the control file descriptor of the epoll object. Close the file descriptor of the epoll object.

Epoll. closed

True if the epoll object is closed. checks whether the epoll object is closed.

Epoll. fileno ()

Return the file descriptor number of the control fd. the file descriptor of the epoll object is returned.

Epoll. fromfd (fd)

Create an epoll object from a given file descriptor. Create an epoll object based on the specified fd

Epoll. register (fd [, eventmask])

Register a fd descriptor with the epoll object. Register the fd and the corresponding event with the epoll object.

Epoll. modify (fd, eventmask)

Modify a registered file descriptor. Modify the fd event

Epoll. unregister (fd)

Remove a registered file descriptor from the epoll object. cancel registration

Epoll. poll (timeout =-1, maxevents =-1)

Wait for events. timeout in seconds (float) blocking until the registered fd event occurs, a dict is returned in the format of {(fd1, event1), (fd2, event2 ),...... (Fdn, eventn )}

Event:


EPOLLIN Available for read is 1

The writable EPOLLOUT Available for write status is 4.

EPOLLPRI Urgent data for read

EPOLLERR Error condition happened on the assoc. fd Error status code 8

EPOLLHUP Hang up happened on the assoc. fd suspension status

EPOLLET Set Edge Trigger behavior. the default is Level Trigger behavior, which is triggered horizontally by default. after this event is Set, Edge triggers

EPOLLONESHOT Set one-shot behavior. After one event is pulled out, the fd is internally disabled

EPOLLRDNORM Equivalent to EPOLLIN

EPOLLRDBAND Priority data band can be read.

EPOLLWRNORM Equivalent to EPOLLOUT

EPOLLWRBAND Priority data may be written.

EPOLLMSG Ignored.

Horizontal trigger and edge trigger:

Level_triggered (horizontal trigger, sometimes called conditional trigger): When a read/write event occurs on the monitored file descriptor, epoll. poll () notifies the handler to read and write data. If this time the data is not fully read (for example, the read/write buffer is too small), the next time epoll is called. poll (), it will also notify you to continue reading and writing on the file descriptor that has not been read and written. of course, if you keep not reading and writing, it will keep notifying you !!! If the system contains a large number of ready file descriptors that you do not need to read or write, and they will be returned each time, this will greatly reduce the efficiency of the processing program to retrieve the ready file descriptor you are concerned about !!! Obvious advantages: stable and reliable

Edge_triggered (edge trigger, sometimes called status trigger): When a read/write event occurs on the monitored file descriptor, epoll. poll () notifies the handler to read and write data. If the data is not fully read this time (for example, the read/write buffer is too small), call epoll next time. poll (), it will not notify you, that is, it will only notify you once, until the second read/write event appears on the file descriptor will notify you !!! This mode is more efficient than horizontal triggering, and the system will not flood with a large number of ready file descriptors you don't care about !!! Disadvantage: unreliable under some conditions

Epoll instance:
import socketimport select s = socket.socket()s.bind(('127.0.0.1',8888))s.listen(5)epoll_obj = select.epoll()epoll_obj.register(s,select.EPOLLIN)connections = {}while True: events = epoll_obj.poll() for fd, event in events:  print(fd,event)  if fd == s.fileno():   conn, addr = s.accept()   connections[conn.fileno()] = conn   epoll_obj.register(conn,select.EPOLLIN)   msg = conn.recv(200)   conn.sendall('ok'.encode())  else:   try:    fd_obj = connections[fd]    msg = fd_obj.recv(200)    fd_obj.sendall('ok'.encode())   except BrokenPipeError:    epoll_obj.unregister(fd)    connections[fd].close()    del connections[fd] s.close()epoll_obj.close()
import socket flag = 1s = socket.socket()s.connect(('127.0.0.1',8888))while flag: input_msg = input('input>>>') if input_msg == '0':  break s.sendall(input_msg.encode()) msg = s.recv(1024) print(msg.decode()) s.close()

The above is the details of the select module instance tutorial in python. For more information, see other related articles in the first PHP community!

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.