亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索

python教程之select模塊介紹

巴扎黑
發(fā)布: 2017-08-16 13:49:30
原創(chuàng)
1394人瀏覽過

簡介

python中的select模塊專注于i/o多路復(fù)用,提供了select ?poll ?epoll三個方法(其中后兩個在linux中可用,windows僅支持select),另外也提供了kqueue方法(freebsd系統(tǒng))

select方法

進程指定內(nèi)核監(jiān)聽哪些文件描述符(最多監(jiān)聽1024個fd)的哪些事件,當沒有文件描述符事件發(fā)生時,進程被阻塞;當一個或者多個文件描述符事件發(fā)生時,進程被喚醒。

當我們調(diào)用select()時:

  1、上下文切換轉(zhuǎn)換為內(nèi)核態(tài)

  2、將fd從用戶空間復(fù)制到內(nèi)核空間

立即進入豆包AI人工智官網(wǎng)入口”;

立即學(xué)習(xí)豆包AI人工智能在線問答入口”;

  3、內(nèi)核遍歷所有fd,查看其對應(yīng)事件是否發(fā)生

  4、如果沒發(fā)生,將進程阻塞,當設(shè)備驅(qū)動產(chǎn)生中斷或者timeout時間后,將進程喚醒,再次進行遍歷

  5、返回遍歷后的fd

  6、將fd從內(nèi)核空間復(fù)制到用戶空間

fd:file descriptor 文件描述符

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

參數(shù): 可接受四個參數(shù)(前三個必須)

rlist: wait until ready for reading

wlist: wait until ready for writing

xlist: wait for an “exceptional condition”

timeout: 超時時間

返回值:三個列表

select方法用來監(jiān)視文件描述符(當文件描述符條件不滿足時,select會阻塞),當某個文件描述符狀態(tài)改變后,會返回三個列表

? ? 1、當參數(shù)1 序列中的fd滿足“可讀”條件時,則獲取發(fā)生變化的fd并添加到fd_r_list中

? ? 2、當參數(shù)2 序列中含有fd時,則將該序列中所有的fd添加到 fd_w_list中

? ? 3、當參數(shù)3 序列中的fd發(fā)生錯誤時,則將該發(fā)生錯誤的fd添加到 fd_e_list中

? ? 4、當超時時間為空,則select會一直阻塞,直到監(jiān)聽的句柄發(fā)生變化

? ?當超時時間 = n(正整數(shù))時,那么如果監(jiān)聽的句柄均無任何變化,則select會阻塞n秒,之后返回三個空列表,如果監(jiān)聽的句柄有變化,則直接執(zhí)行。

實例:

利用select實現(xiàn)一個可并發(fā)的服務(wù)端

import socket
import select
 
s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
r_list = [s,]
num = 0
while 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()
登錄后復(fù)制
import socket
 
flag = 1
s = 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()
登錄后復(fù)制

在服務(wù)端我們可以看到,我們需要不停的調(diào)用select, 這就意味著:

  1 ?當文件描述符過多時,文件描述符在用戶空間與內(nèi)核空間進行copy會很費時

  2 ?當文件描述符過多時,內(nèi)核對文件描述符的遍歷也很浪費時間

  3 ?select最大僅僅支持1024個文件描述符

poll與select相差不大,本文不作介紹

epoll方法:

epoll很好的改進了select:

  1、epoll的解決方案在epoll_ctl函數(shù)中。每次注冊新的事件到epoll句柄中時,會把所有的fd拷貝進內(nèi)核,而不是在epoll_wait的時候重復(fù)拷貝。epoll保證了每個fd在整個過程中只會拷貝一次。

  2、epoll會在epoll_ctl時把指定的fd遍歷一遍(這一遍必不可少)并為每個fd指定一個回調(diào)函數(shù),當設(shè)備就緒,喚醒等待隊列上的等待者時,就會調(diào)用這個回調(diào)函數(shù),而這個回調(diào)函數(shù)會把就緒的fd加入一個就緒鏈表。epoll_wait的工作實際上就是在這個就緒鏈表中查看有沒有就緒的fd

  3、epoll對文件描述符沒有額外限制

select.epoll(sizehint=-1, flags=0) 創(chuàng)建epoll對象

?

豆包AI編程
豆包AI編程

豆包推出的AI編程助手

豆包AI編程483
查看詳情 豆包AI編程

epoll.close()

Close the control file descriptor of the epoll object.關(guān)閉epoll對象的文件描述符

?

epoll.closed

True if the epoll object is closed.檢測epoll對象是否關(guān)閉

?

epoll.fileno()

Return the file descriptor number of the control fd.返回epoll對象的文件描述符

?

epoll.fromfd(fd)

Create an epoll object from a given file descriptor.根據(jù)指定的fd創(chuàng)建epoll對象

?

epoll.register(fd[, eventmask])

Register a fd descriptor with the epoll object.向epoll對象中注冊fd和對應(yīng)的事件

?

epoll.modify(fd, eventmask)

Modify a registered file descriptor.修改fd的事件

?

epoll.unregister(fd)

Remove a registered file descriptor from the epoll object.取消注冊

?

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

Wait for events. timeout in seconds (float)阻塞,直到注冊的fd事件發(fā)生,會返回一個dict,格式為:{(fd1,event1),(fd2,event2),……(fdn,eventn)}

事件:

EPOLLIN Available for read 可讀 狀態(tài)符為1

EPOLLOUT Available for write 可寫 狀態(tài)符為4

EPOLLPRI Urgent data for read

EPOLLERR Error condition happened on the assoc. fd 發(fā)生錯誤 狀態(tài)符為8

EPOLLHUP Hang up happened on the assoc. fd 掛起狀態(tài)

EPOLLET Set Edge Trigger behavior, the default is Level Trigger behavior 默認為水平觸發(fā),設(shè)置該事件后則邊緣觸發(fā)

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.

水平觸發(fā)和邊緣觸發(fā):

Level_triggered(水平觸發(fā),有時也稱條件觸發(fā)):當被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時,epoll.poll()會通知處理程序去讀寫。如果這次沒有把數(shù)據(jù)一次性全部讀寫完(如讀寫緩沖區(qū)太小),那么下次調(diào)用 epoll.poll()時,它還會通知你在上沒讀寫完的文件描述符上繼續(xù)讀寫,當然如果你一直不去讀寫,它會一直通知你?。?!如果系統(tǒng)中有大量你不需要讀寫的就緒文件描述符,而它們每次都會返回,這樣會大大降低處理程序檢索自己關(guān)心的就緒文件描述符的效率?。。?優(yōu)點很明顯:穩(wěn)定可靠

Edge_triggered(邊緣觸發(fā),有時也稱狀態(tài)觸發(fā)):當被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時,epoll.poll()會通知處理程序去讀寫。如果這次沒有把數(shù)據(jù)全部讀寫完(如讀寫緩沖區(qū)太小),那么下次調(diào)用epoll.poll()時,它不會通知你,也就是它只會通知你一次,直到該文件描述符上出現(xiàn)第二次可讀寫事件才會通知你?。?!這種模式比水平觸發(fā)效率高,系統(tǒng)不會充斥大量你不關(guān)心的就緒文件描述符?。。∪秉c:某些條件下不可靠

epoll實例:

import socket
import 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()
登錄后復(fù)制
import socket
 
flag = 1
s = 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()
登錄后復(fù)制

以上就是python教程之select模塊介紹的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!

相關(guān)標簽:
python速學(xué)教程(入門到精通)
python速學(xué)教程(入門到精通)

python怎么學(xué)習(xí)?python怎么入門?python在哪學(xué)?python怎么學(xué)才快?不用擔(dān)心,這里為大家提供了python速學(xué)教程(入門到精通),有需要的小伙伴保存下載就能學(xué)習(xí)啦!

下載
來源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn
最新問題
開源免費商場系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長!
關(guān)注服務(wù)號 技術(shù)交流群
PHP中文網(wǎng)訂閱號
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號