Linux系统中IO多路复用select函数的使用,及其在Android系统中的运用

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一个新的应用进程

 Android系统的心脏-Zygote进程启动流程分析


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值