Linux从入门到开发实战(C/C++)Day09-select

select是什么:是一种轮询方式(遍历)实现的IO多路复用

IO多路复用是什么:让输入/输出设备能多次使用(复用),现在因为有 阻塞(accept、recv等函数造成) 所以不能多次使用

  • select        适用于小数量级        是阻塞的
  • poll            很少用
  •  epoll         适用于大数量级        事件(通知)的方式实现

IO操作(accept、recv)前,先判断是否有动静(有数据可读、可写)若有,再执行io操作,没有则不执行

        IO多路复用监视的是文件描述符号
        fd_set 文件描述集合,类似数组
        #include <sys/select.h>
           int select(
                    int nfds,                    //文件描述符号限制,一般是最大描述符号+1
                    fd_set *readfds,             //输入描述符号集合
                    fd_set *writefds,            //output fds
                    fd_set *exceptfds,             //erroroutput fds
                    struct timeval *timeout        //延时
                );
        void FD_CLR(int fd, fd_set *set);        //把fd从fds中删除
        int  FD_ISSET(int fd, fd_set *set);        //查找描述符号
        void FD_SET(int fd, fd_set *set);        //把fd放入fds中
        void FD_ZERO(fd_set *set);                //清空描述符号集

        select编程模型:
            1.创建描述符号集
            2.放入要监视的描述符号
            3.监视(阻塞式)
            4.根据监视返回的值进行对应事件处理
            5.循环2-4

void _select()
{
	fd_set fds;
	fd_set fdsOut;

	// FD_ZERO(&fds);
	FD_ZERO(&fdsOut);
	// FD_SET(0,&fds);
	FD_SET(1, &fdsOut);

	int r;
	char buff[1024];
	while (1)
	{
		FD_ZERO(&fds);
		FD_SET(0, &fds);
		r = select(2, &fds, &fdsOut, NULL, NULL);
		if (r > 0)
		{
			if (FD_ISSET(0, &fds))
			{
				printf("是0有动静\n");
				scanf("%s", buff);
			}

			if (FD_ISSET(1, &fdsOut))
			{
				printf("是1有动静\n");
				FD_CLR(1, &fdsOut);
				FD_ZERO(&fdsOut);
			}
			printf("r:%d\n", r);
		}
		else if (0 == r)
		{
			printf("没有动静\n");
		}
		else
		{
			printf("错误:%m\n");
		}
		// 处理完之后要清除
		//  FD_CLR(0,&fds);
		// 再重新放回去
		//  FD_SET(0,&fds);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_55149044/article/details/142097652