Linux编程之select用法

一、C语言用法

  • 函数模型:

     int select (int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  • 相关头文件

       #i nclude<sys/time.h>
       #i nclude<sys/types.h>
       #i nclude<unistd.h>

  • 参数说明

      int maxfdp:是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1

        fd_set *readfds:  一组发起读请求的文件描述苻,linux中一切皆文件。

        fd_set *writefds:一组发起读请求的文件描述苻。

        fd_set *exceptfds: 用来监视文件错误异常

        struct timeval *timeout:struct timeval *timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间。

  • 相关函数

           select()用来等待文件描述词状态的改变。参数n代表最大的文件描述词加1,参数readfds、writefds 和exceptfds 称为描述词组,是用来回传该描述词的读,写或例外的状况。底下的宏提供了处理这三种描述词组的方式:

          FD_CLR(inr fd,fd_set* set);用来清除描述词组set中相关fd 的位

          FD_ISSET(int fd,fd_set *set);用来测试描述词组set中相关fd 的位是否为真

          FD_SET(int fd,fd_set*set);用来设置描述词组set中相关fd的位

          FD_ZERO(fd_set *set); 用来清除描述词组set的全部位

需要注意的地方:

       1、如果在一个文件描述苻上碰到了文件结尾处,则select认为该描述苻是可读的。然后调用read,返回0。

  • 实例之c语言

#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
        
        

#include
        
        
          #include 
         
           #include 
          
            int main() { int keyboard; int ret, i; char c; fd_set readfd; struct timeval timeout; keyboard = open("/dev/tty", O_RDONLY|O_NONBLOCK); assert(keyboard > 0); while(1) { timeout.tv_sec = 1; timeout.tv_usec = 0; FD_ZERO(&readfd); FD_SET(keyboard, &readfd); ret = select(keyboard+1, &readfd, NULL, NULL, &timeout); if(FD_ISSET(keyboard, &readfd)) { i = read(keyboard, &c, 1); if('\n' == c) continue; printf("the put is %c\n",c); if('q' == c) break; } } } 
           
          
        
       
       
      
      
     
     
    
    

  • 实例之python

#! /usr/bin/env python

import select

BLKSIZE = 20

def readwrite(fromfd,tofd):
	readbuf = fromfd.read(BLKSIZE)
	if readbuf:
		tofd.write(readbuf)
		tofd.flush
	return len(readbuf)

def copyfile(fromfd1,tofd1,fromfd2,tofd2):
	totalbytes = 0
	if not (fromfd1 or fromfd2 or tofd1 or tofd2):
		return 0
	while True:
		rs,ws,es = select.select([fromfd1,fromfd2],[],[])
		for r in rs:
			if r is fromfd1:
				bytesread1 = readwrite(fromfd1,tofd1)
				totalbytes += bytesread1
				print "copy from1 %d bytes" % bytesread1
			if r is fromfd2:
				bytesread2 = readwrite(fromfd2,tofd2)
				totalbytes += bytesread2
				print "copy from2 %d bytes" % bytesread2
		if(bytesread1 <= 0 and bytesread2 <=0): #这里需要等到最大的文件复制完
			break
	return totalbytes

def main():
	fromfd1 = open("/etc/passwd", "r")
	fromfd2 = open("/etc/fstab", "r")

	tofd1 = open("/home/lirifeng/passwd","w+")
	tofd2 = open("/home/lirifeng/fstab","w+")

	totalbytes = copyfile(fromfd1,tofd1,fromfd2,tofd2)

	print "Number of bytes copied %d" % totalbytes
	return 0

if __name__ == "__main__":
	main()


    另有select在socket编程中的用法,见链接http://zyg0227.blog.51cto.com/1043164/554208

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值