python IO 多路復(fù)用(select)

了解了IO多路復(fù)用矢渊,我們就來看看python中是如何使用的继准。Python中有一個select模塊,其中提供了:select矮男、poll移必、epoll三個方法,分別調(diào)用系統(tǒng)的 select毡鉴,poll崔泵,epoll 從而實現(xiàn)IO多路復(fù)用。(下面以select方法為例)

Windows Python:

提供: select

Mac Python:

提供: select

Linux Python:

提供: select猪瞬、poll憎瘸、epoll

注意:網(wǎng)絡(luò)操作、文件操作陈瘦、終端操作等均屬于IO操作幌甘,對于windows只支持Socket操作,其他系統(tǒng)支持其他IO操作痊项,但是無法檢測 普通文件操作 自動上次讀取是否已經(jīng)變化锅风。

對于select方法:

句柄列表11, 句柄列表22, 句柄列表33=select.select(句柄序列1, 句柄序列2, 句柄序列3, 超時時間)

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

返回值:三個列表

select方法用來監(jiān)視文件句柄,如果句柄發(fā)生變化鞍泉,則獲取該句柄皱埠。

1、當(dāng) 參數(shù)1序列中的句柄發(fā)生可讀時(accetp和read)咖驮,則獲取發(fā)生變化的句柄并添加到 返回值1序列中

2边器、當(dāng) 參數(shù)2序列中含有句柄時,則將該序列中所有的句柄添加到 返回值2序列中

3托修、當(dāng) 參數(shù)3序列中的句柄發(fā)生錯誤時忘巧,則將該發(fā)生錯誤的句柄添加到 返回值3序列中

4、當(dāng) 超時時間 未設(shè)置诀黍,則select會一直阻塞袋坑,直到監(jiān)聽的句柄發(fā)生變化(時間設(shè)置)

當(dāng) 超時時間 =1時,那么如果監(jiān)聽的句柄均無任何變化眯勾,則select會阻塞1秒枣宫,之后返回三個空列表,如果監(jiān)聽的句柄有變化吃环,則直接執(zhí)行也颤。

利用select實現(xiàn)偽同時處理多個Socket客戶端請求:服務(wù)端

!/usr/bin/python

-- coding: utf-8 --

"""
@version: ??
@author: Guanjie Zhou
@license: Apache Licence
@file: server.py
@time: 17-5-25 下午9:50
"""

'''
服務(wù)器的實現(xiàn) 采用select的方式
'''

import select
import socket
import sys
import Queue

創(chuàng)建套接字并設(shè)置該套接字為非阻塞模式

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)

綁定套接字

server_address = ('localhost', 10000)

server.bind(server_address)

將該socket變成服務(wù)模式

backlog等于5,表示內(nèi)核已經(jīng)接到了連接請求郁轻,但服務(wù)器還沒有調(diào)用accept進行處理的連接個數(shù)最大為5

這個值不能無限大翅娶,因為要在內(nèi)核中維護連接隊列

server.listen(5)

初始化讀取數(shù)據(jù)的監(jiān)聽列表,最開始時希望從server這個套接字上讀取數(shù)據(jù)

inputs = [server]

初始化寫入數(shù)據(jù)的監(jiān)聽列表,最開始并沒有客戶端連接進來好唯,所以列表為空

outputs = []

要發(fā)往客戶端的數(shù)據(jù)

message_queues = {}
while inputs:
print('waiting for the next event')
# 調(diào)用select監(jiān)聽所有監(jiān)聽列表中的套接字竭沫,并將準(zhǔn)備好的套接字加入到對應(yīng)的列表中
readable, writable, exceptional = select.select(inputs, outputs, inputs) # 列表中的socket 套接字 如果是文件呢?
# 監(jiān)控文件句柄有某一處發(fā)生了變化 可寫 可讀 異常屬于Linux中的網(wǎng)絡(luò)編程
# 屬于同步I/O操作骑篙,屬于I/O復(fù)用模型的一種
# rlist--等待到準(zhǔn)備好讀
# wlist--等待到準(zhǔn)備好寫
# xlist--等待到一種異常
# 處理可讀取的套接字

'''
    如果server這個套接字可讀蜕提,則說明有新鏈接到來
    此時在server套接字上調(diào)用accept,生成一個與客戶端通訊的套接字
    并將與客戶端通訊的套接字加入inputs列表,下一次可以通過select檢查連接是否可讀
    然后在發(fā)往客戶端的緩沖中加入一項靶端,鍵名為:與客戶端通訊的套接字谎势,鍵值為空隊列
    select系統(tǒng)調(diào)用是用來讓我們的程序監(jiān)視多個文件句柄(file descrīptor)的狀態(tài)變化的。程序會停在select這里等待杨名,
    直到被監(jiān)視的文件句柄有某一個或多個發(fā)生了狀態(tài)改變
    '''

'''
    若可讀的套接字不是server套接字,有兩種情況:一種是有數(shù)據(jù)到來脏榆,另一種是鏈接斷開
    如果有數(shù)據(jù)到來,先接收數(shù)據(jù),然后將收到的數(shù)據(jù)填入往客戶端的緩存區(qū)中的對應(yīng)位置,最后
    將于客戶端通訊的套接字加入到寫數(shù)據(jù)的監(jiān)聽列表:
    如果套接字可讀.但沒有接收到數(shù)據(jù)台谍,則說明客戶端已經(jīng)斷開须喂。這時需要關(guān)閉與客戶端連接的套接字
    進行資源清理
    '''
print ('111')

for s in readable:
    if s is server:
        connection, client_address = s.accept()
        print('connection from', client_address)
        connection.setblocking(0)  # 設(shè)置非阻塞
        inputs.append(connection)
        # 將新連接的套接字鏈接通話建立到一個隊列中去
        message_queues[connection] = Queue.Queue()
    else:
        data = s.recv(1024).decode()
        if data:
            print('received "%s" from %s' % \
                  (data, s.getpeername()))
            message_queues[s].put(data)
            if s not in outputs:
                # 不存在outputs列表中的,加入到outputs中
                outputs.append(s)
        else:
            print('closing', client_address)
            if s in outputs:
                outputs.remove(s)
            inputs.remove(s)
            s.close()
            del message_queues[s]

# 處理可寫的套接字
'''
    在發(fā)送緩沖區(qū)中取出響應(yīng)的數(shù)據(jù)趁蕊,發(fā)往客戶端镊折。
    如果沒有數(shù)據(jù)需要寫,則將套接字從發(fā)送隊列中移除介衔,select中不再監(jiān)視
    '''

for s in writable:
    try:
        next_msg = message_queues[s].get_nowait()

    except Queue.Empty:
        print('  ', s.getpeername(), 'queue empty')
        outputs.remove(s)
    else:
        print('sending "%s" to %s' % \
              (next_msg, s.getpeername()))
        s.send(next_msg)

# 處理異常情況

for s in exceptional:
    for s in exceptional:
        print('exception condition on', s.getpeername())
        inputs.remove(s)
        if s in outputs:
            outputs.remove(s)
        s.close()
        del message_queues[s]

利用select監(jiān)聽終端操作實例

!/usr/bin/python

-- coding: utf-8 --

"""
@version: ??
@author: Guanjie Zhou
@license: Apache Licence
@file: client.py
@time: 17-5-26 下午1:11
"""

import socket

ip_port= ('127.0.0.1',10000)
sk = socket.socket()
sk.connect(ip_port)

while True:
inp = raw_input("please input:").encode()
sk.sendall(inp)
data = sk.recv(1024).decode()
print data+'hello'
sk.close()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恨胚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子炎咖,更是在濱河造成了極大的恐慌赃泡,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乘盼,死亡現(xiàn)場離奇詭異升熊,居然都是意外死亡,警方通過查閱死者的電腦和手機绸栅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門级野,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粹胯,你說我怎么就攤上這事蓖柔〕狡螅” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵况鸣,是天一觀的道長牢贸。 經(jīng)常有香客問我,道長镐捧,這世上最難降的妖魔是什么潜索? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮懂酱,結(jié)果婚禮上竹习,老公的妹妹穿的比我還像新娘。我一直安慰自己列牺,他們只是感情好整陌,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昔园,像睡著了一般蔓榄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上默刚,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天甥郑,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛巫湘,可吹牛的內(nèi)容都是我干的儡率。 我是一名探鬼主播工禾,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饵溅,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妇萄,沒想到半個月后蜕企,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡冠句,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年轻掩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懦底。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡唇牧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丐重,我是刑警寧澤腔召,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站弥臼,受9級特大地震影響宴咧,放射性物質(zhì)發(fā)生泄漏根灯。R本人自食惡果不足惜径缅,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烙肺。 院中可真熱鬧纳猪,春花似錦、人聲如沸桃笙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搏明。三九已至鼠锈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間星著,已是汗流浹背购笆。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留虚循,地道東北人同欠。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像横缔,于是被迫代替她去往敵國和親铺遂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容