python的select,poll,epoll用法


Python代码     收藏代码  

  1. #!/usr/bin/env python  

  2. #coding=utf-8  

  3. import os  

  4. import fcntl  

  5. import select, sys, subprocess  

  6.   

  7. vmstat_pipe = subprocess.Popen('netstat', shell=True, bufsize=1024,   

  8.         stdout=subprocess.PIPE).stdout  

  9. iostat_pipe = subprocess.Popen('top', shell=True, bufsize=1024,   

  10.         stdout=subprocess.PIPE).stdout  

上面是通用代码,下面会分别用select,poll,epoll来进行读管道的数据

1.select

Python代码     收藏代码  

  1. while 1:  

  2.     infds,outfds,errfds = select.select([vmstat_pipe,iostat_pipe],[],[],5000)  

  3.     if len(infds) != 0:  

  4.         for m in infds:  

  5.             msg = m.readline()  

  6.             print "Get ", msg, "from pipe", m  

2.poll

Python代码     收藏代码  

  1. pipe_dict = {vmstat_pipe.fileno():vmstat_pipe, iostat_pipe.fileno():iostat_pipe}  

  2. p = select.poll()  

  3. p.register(vmstat_pipe, select.POLLIN|select.POLLERR|select.POLLHUP)  

  4. p.register(iostat_pipe, select.POLLIN|select.POLLERR|select.POLLHUP)  

  5. while 1:  

  6.     result = p.poll(5000)  

  7.     if len(result) != 0:  

  8.         for m in result:  

  9.             if m[1] & select.POLLIN:  

  10.                 print "Get", pipe_dict[m[0]].readline(), "from pipe", m[0]  

3.epoll

与poll的代码基本一致,只是改为epoll即可:p = select.epoll()

阻塞与非阻塞:

注意上例中都是用的readline(),而没有用read(),原因是用read()会导致阻塞,读不到数据;如果想要用read(),那么

需要设置管道为非阻塞的:

Python代码     收藏代码  

  1. fl = fcntl.fcntl(vmstat_pipe.fileno(), fcntl.F_GETFL)  

  2. fcntl.fcntl(vmstat_pipe.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)  

  3. fl = fcntl.fcntl(iostat_pipe.fileno(), fcntl.F_GETFL)  

  4. fcntl.fcntl(iostat_pipe.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)  

另外如果管道的写端关闭,会读到一个文件结束符,比如上面代码的vmstat_pipe管道写端关闭后,会一直读到文件

你可能感兴趣的:(python的select,poll,epoll用法)