Select 系统调用:
select系统调用是用来监视多个文件句柄的状态的。程序会停在select这里等待,直到被监视的文件句柄有某一个或多个发生了状态改变,或者到了超时时间。
具体的select系统调用的参数可以看看man手册里面的说明,这里我们用一个用户空间的事例来解释说明一下这个系统调用的用法:
int main(void)
{
int fd1,fd2,max_fd;
int i;
fd_set fdR;
struct timeval timeout;
//这里我们打开一个内核注册的字符设备select1
fd1 = open("/dev/select1",0666);
if(fd1 < 0)
{
printf("Open select1 failure!/n");
exit(0);
}
//同上的fd1
fd2 = open("/dev/select2",0666);
if(fd2 < 0)
{
printf("Open select2 failure!/n");
exit(0);
}
if(fd1 > fd2)
max_fd = fd1+1;
else
max_fd = fd2+1;
//这里我们随便设置了个超时时间为1秒
timeout.tv_sec = 1;
timeout.tv_usec = 0;
for(i = 0;i<10;i++)
{
//先把fdR清零,然后把两个字符设备的句柄添加到fdR中
FD_ZERO(&fdR);
FD_SET(fd1,&fdR);
FD_SET(fd2,&fdR);
//用select系统调用来判断哪个字符设备可读select系统调用的返回值为可读的字符设备的个数
switch(select(max_fd,&fdR,NULL,NULL,&timeout))
{
case -1:
printf("select handle error!/n");
break;
case 0:
printf("select timeout!/n");
break;
default:
//这里fdR通过系统调用之后被刷新成可读的设备句柄的集合了
if(FD_ISSET(fd1,&fdR))
printf("select 1 can read now!/n");
if(FD_ISSET(fd2,&fdR))
printf("select 2 can read now!/n");
break;
}
printf("/n");
}
return 0;
}
在内核中注册了两个字符设备,在响应用户空间系统调用select的时候,执行的是struct file_operations结构中的poll函数,在poll函数中做相应的判断处理之后进行给予相应的返回值既可。具体的返回值可以参考net/ipv4/tcp.c中的源码中的tcp_poll函数的操作。