Linux系统中IO多路复用select函数的使用,及其在Android系统中的运用
Linux中提供了select系统调用来监听文件描述符的事件,可以实现I/O的多路复用,例如键盘输入事件,socket事件等。
select简介:
Linux中提供了select系统调用来监听文件描述符的事件,可以实现I/O的多路复用,例如键盘输入事件,socket事件等。
select函数的使用:
声明:
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);
//一下,是相关函数
int FD_ZERO(int fd, fd_set *fdset); //所有位都设为 0
int FD_CLR(int fd, fd_set *fdset); //清除某个位时可以使用
int FD_SET(int fd, fd_set *fd_set); //设置变量的某个位置位
int FD_ISSET(int fd, fd_set *fdset); //测试某个位是否被置位
参数说明:
maxfdp:被监听的文件描述符的总数,它比所有文件描述符集合中的文件描述符的最大值大1,因为文件描述符是从0开始计数的;
readfds、writefds、exceptset:分别指向可读、可写和异常等事件对应的描述符集合;
timeout:用于设置select函数的超时时间,timeout == NULL 表示等待无限长的时间
timeval结构体定义如下:
struct timeval
{
long tv_sec; /*秒 */
long tv_usec; /*微秒 */
};
返回值:超时返回0;失败返回-1;成功返回大于0的整数,这个整数表示就绪描述符的数目。
select函数使用举例:
功能:接收从标准输入(在电脑上,标准输入通常为键盘)的值,设置超时,如果时间到,就结束。
#include <stdlib.h>
#include <stdio.h>
//#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
/* 标准输入 */
#define STDIN 0
int main()
{
struct timeval tv;
fd_set read_fds;
int err;
//等待2s+100000微秒
tv.tv_sec = 2;
tv.tv_usec = 100000;
FD_ZERO(&read_fds);
FD_SET(STDIN,&read_fds);
select(STDIN+1,&read_fds,NULL,NULL,&tv);
if (FD_ISSET(STDIN, &read_fds)) {
printf("有数据输入!\n");
}else {
printf("time out!\n");
}
return 0;
}
运行:
% gcc select_test.c
% ./a.out
time out! //什么都没有输,2s多后就时间到了
% ./a.out
abcdtime out! //输入abcd,这时,时间到,输出abcd后,再输出time out!
select可以接受来自键盘的输入事件。本质上,在linux中,所有的资源都是文件,所以,select可以监听到标准输入事件。
select更多的被应用于socket套接字中,进行网络数据的I/O多路复用。
select函数在Android系统的运用:
在Android系统中,所有的应用程序进程都是由Zygote进程创建的,那么,zygote进程怎么知道“现在该创建进程了?”,者就是“通过select监听来自客户端套接字的请求”来实现的。
来看代码:
1.java层:ZygoteInit.java:
1.1 runSelectLoopMode
1.1.1 static native int selectReadable(FileDescriptor[] fds) throws IOException; --->
2. natiove层:com_android_internal_os_ZygoteInit_selectReadable函数:
do { err = select (nfds, &fdset, NULL, NULL, NULL); } while (err < 0 && errno == EINTR);
具体可以参考:
Android系统的心脏-Zygote进程如何fork一个新的应用进程
更多推荐
所有评论(0)