V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yang2yang
V2EX  ›  Python

python 中 select 函数求解

  •  1
     
  •   yang2yang ·
    yang2yang · 2015-10-07 17:14:30 +08:00 · 2798 次点击
    这是一个创建于 3138 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 select 的服务器

    import select
    import socket
    import Queue
    
    #create a socket
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.setblocking(False)
    #set option reused
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR , 1)
    
    server_address= ('localhost',10001)
    server.bind(server_address)
    
    server.listen(10)
    
    #sockets from which we except to read
    inputs = [server]
    
    #sockets from which we expect to write
    outputs = []
    
    #Outgoing message queues (socket:Queue)
    message_queues = {}
    
    #A optional parameter for select is TIMEOUT
    timeout = 10
    
    while inputs:
        print "waiting for next event"
    #--------------------------------------------------
        readable , writable , exceptional = select.select(inputs, outputs, inputs)
    #--------------------------------------------------
        for temp in readable:
            print temp
        print "writable:",writable
        print "exceptional",exceptional
    
        # When timeout reached , select return three empty lists
        if not (readable or writable or exceptional) :
            print "Time out ! "
            break;
        for s in readable :
            if s is server:
                # A "readable" socket is ready to accept a connection
                connection, client_address = s.accept()
                print "    connection from ", client_address
                connection.setblocking(0)
                inputs.append(connection)
                message_queues[connection] = Queue.Queue()
                ...........................
    

    创建十个 socket 用于连接服务器

    import socket
    
    messages = ["This is the message" ,
                "It will be sent" ,
                "in parts "]
    
    print "Connect to the server"
    
    server_address = ("localhost",10001)
    
    #Create a TCP/IP sock
    
    socks = []
    
    for i in range(10):
        socks.append(socket.socket(socket.AF_INET,socket.SOCK_STREAM))
    
    for s in socks:
        s.connect(server_address)
    
    counter = 0
    for message in messages :
        #Sending message from different sockets
        for s in socks:
            counter+=1
            print "  %s sending %s" % (s.getpeername(),message+" version "+str(counter))
            s.send(message+" version "+str(counter))
        #Read responses on both sockets
        for s in socks:
            data = s.recv(1024)
            print " %s received %s" % (s.getpeername(),data)
            if not data:
                print "closing socket ",s.getpeername()
                s.close()
    

    问题:
    ( 1 )服务器例子中的 select 函数是在一个怎么样的条件下才会返回?
    ( 2 )是不是只要有一个 socket 进行连接就会进行返回?还是说等到十个 socket 都连接了才返回?
    ( 3 )可以的话,讲讲 select 函数具体的运作过程?求解惑, thx

    5 条回复    2015-10-07 23:39:37 +08:00
    RTNelo
        1
    RTNelo  
       2015-10-07 18:39:23 +08:00
    yang2yang
        2
    yang2yang  
    OP
       2015-10-07 19:24:54 +08:00
    好的,其实我也是看过类似的文档。但是,可能我没看到,或者说不能完全理解(毕竟 English 不是很好 。。。。)刚才也是读了这个文档,在这个官方文档中还是没有提到 select 函数在 timeout 不填的时候返回时,是等到全部的 socket 连接入,还是只要有一个 socket 连入就返回。下面这两句应该是指 timeout 有值和 timeout 为 0 时的情况??还是说为 0 的情况和不填的情况是一样的?
    When the timeout argument is omitted the function blocks until at least one file descriptor is ready.A time-out value of zero specifies a poll and never blocks.
    mckelvin
        3
    mckelvin  
       2015-10-07 21:57:12 +08:00
    @yang2yang 上面的英语描述已经解答了你的疑惑了啊!

    > 下面这两句应该是指 timeout 有值和 timeout 为 0 时的情况??还是说为 0 的情况和不填的情况是一样的?

    - 不指定 timeout 的情况下,只要有 >= 1 个文件描述符响应了就立即返回,否则一直阻塞着。
    - timeout = 0 的情况下,永远不阻塞(立即返回)
    - timeout > 0 的情况下,有 >= 1 个文件描述符响应了就立即返回,如果过了 timeout 时间一个文件描述符都没响应的话,那就不等待了,立即返回。

    建议阅读:

    - http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/#comment-39719
    yang2yang
        4
    yang2yang  
    OP
       2015-10-07 23:20:59 +08:00
    谢谢回复的各位,明白了
    ryd994
        5
    ryd994  
       2015-10-07 23:39:37 +08:00 via Android
    要是必须全部响应才返回的话,还要 select 干嘛?直接一个个 blocking 地读过去不就完了吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   983 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:58 · PVG 04:58 · LAX 13:58 · JFK 16:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.