select() linux,Linux select()详解

Linux select()详解

(2011-07-17 23:50:39)

标签:

杂谈

Linux select()详解 select系统调用是用来让我们的过程监视多个文件句柄(file

descriptor)的事态改变的。过程会停在select这里期待,直到被监视的文件句柄有某一个或多个发生了事态改换。

文件在句柄在Linux里许多,万一你man某个函数,在函数归来值局部说到获胜后有一个文件句柄被创立的都是的,如man

socket能够看到“On success, a file descriptor for the

new socket is returned.”而man 2

open能够看到“open() and creat() return the new file

descriptor”,其实文件句柄即便一个整数,看socket函数的声明就打听了:

int socket(int domain, int type, int protocol);

当然,我们最纯熟的句柄是0、1、2三个,0是规范输入,1是规范输出,2是规范讹谬输出。0、1、2是整数表示的,对应的FILE

*构造的表示即便stdin、stdout、stderr,0即便stdin,1即便stdout,2即便stderr。

例如下面这两段代码都是从规范输入读入9个字节字符:

#include

#include

#include

int main(int argc, char ** argv)

{

char buf[10] = "";

read(0, buf, 9);

fprintf(stdout, "%s/n", buf);

return 0;

}

#include

#include

#include

int main(int argc, char ** argv)

{

char buf[10] = "";

fread(buf, 9, 1, stdin);

write(1, buf, strlen(buf));

return 0;

}

继续上面说的select,即便用来监视某个或某些句柄的事态改变的。select函数原型如下:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set

*exceptfds, struct timeval *timeout);

函数的最后一个参数timeout显明是一个超随工夫值,其种类是struct timeval *,即一个struct

timeval构造的变量的指针,因而我们在过程里要声明一个struct timeval

tv;然后把变量tv的地址&tv递交给select函数。struct

timeval构造如下:

struct timeval {

long tv_sec;

long tv_usec;

};

第2、3、4三个参数是一样的种类: fd_set *,即我们在过程里要声明几个fd_set种类的变量,例如rdfds, wtfds,

exfds,然后把这个变量的地址&rdfds, &wtfds,

&exfds

递交给select函数。这三个参数都是一个句柄的聚集,第一个rdfds是用来保留这么的句柄的:当句柄的事态变成可读的时系统就会告诉select函数归来,同理第二个wtfds是指有句柄事态变成可写的时系统就会告诉select函数归来,同理第三个参数exfds是特异情形,即句柄上有特异情形发生时系统会告诉select函数归来。特异情形例如对手穿越一个socket句柄发来了紧迫数据。万一我们过程里只想检测某个socket是否有数据可读,我们能够这么:

fd_set rdfds;

struct timeval tv;

int ret;

FD_ZERO(&rdfds);

FD_SET(socket, &rdfds);

tv.tv_sec = 1;

tv.tv_usec = 500;

ret = select(socket + 1, &rdfds, NULL, NULL,

&tv);

if(ret < 0) perror("select");

else if(ret == 0) printf("超时/n");

else {

printf("ret=%d/n", ret);

if(FD_ISSET(socket, &rdfds)) {

recv(...);

}

}

当心select函数的第一个参数,是所有加入聚集的句柄值的最大那个值还要加1。例如我们创立了3个句柄:

int sa, sb, sc;

sa = socket(...);

connect(sa,...);

sb = socket(...);

connect(sb,...);

sc = socket(...);

connect(sc,...);

FD_SET(sa, &rdfds);

FD_SET(sb,Lumi &rdfds);

FD_SET(sc, &rdfds);

在利用select函数之前,定然要找到3个句柄中的最大值是哪个,我们等闲定义一个变量来保留最大值,获得最大socket值如下:

int maxfd = 0;

if(sa > maxfd) maxfd = sa;

if(sb > maxfd) maxfd = sb;

if(sc > maxfd) maxfd = sc;

然后调用select函数:

ret = select(maxfd + 1, &rdfds, NULL, NULL,

&tv);

同样的理由,万一我们要检测用户是否按了键盘举行输入,我们就该当把规范输入0这个句柄放到select里来检测,如下:

FD_ZERO(&rdfds);

FD_SET(0, &rdfds);

tv.tv_sec = 1;

tv.tv_usec = 0;

ret = select(1, &rdfds, NULL, NULL,

&tv);

if(ret < 0) perror("select");

else if(ret == 0) printf("超时/n");

else {

scanf("%s", buf);

}

将对社会生态带来宏伟的波及。

分享:

a4c26d1e5885305701be709a3d33442f.png喜欢

0

a4c26d1e5885305701be709a3d33442f.png赠金笔

加载中,请稍候......

评论加载中,请稍候...

发评论

登录名: 密码: 找回密码 注册记住登录状态

昵   称:

评论并转载此博文

a4c26d1e5885305701be709a3d33442f.png

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值