1.18号网络

阻塞IO

1> 最常用、最常见的,效率最低的操作

2> 当IO事件没有得到满足时,IO相关函数不会返回,只有当IO事件满足后,对应函数才会解除阻塞

3> 目前接触的阻塞函数:scanf、getchar、read、write、recv、accept

非阻塞IO

1> 防止进程在IO操作上进行阻塞,如果对应缓冲区中没有数据,想使程序直接执行后续操作,而不再IO操作上阻塞

2> fcntl

       #include
       #include

       int fcntl(int fd, int cmd, ... /* arg */ );
功能:获取或设置文件描述符的属性
参数1:要设置的文件描述符
参数2:指令,根据不同的指令,该函数执行不同功能
        F_GETFL:获取文件描述符的属性,如果cmd为该值,则第三个参数可以忽略
        F_SETFL:设置文件描述符的属性,如果cmd为该值,则第三个参数为int类型
参数3:根据参数2而定,如果cmd为该值,则第三个参数为int类型表示要设置文件描述符的状态
        O_RDONLY,  O_WRONLY,  O_RDWR, O_APPEND,  O_ASYNC,  O_DIRECT,  O_NOATIME,  O_NONBLOCK(非阻塞属性)
返回值:如果参数为F_SETFL,成功返回当前文件描述符的状态,失败返回-1并置位错误码
       

如果参数为F_GETFL,成功返回0,失败返回-1并置位错误码

使用方法: int arg = fcntl(0, F_GETFL); //获取文件描述符之前的状态 arg = arg|O_NONBLOCK; //加上其他属性 fcntl(0, F_SETFL, arg); //将改变后的属性设置回去

IO多路复用

1> 对于多个阻塞任务想要并发执行时,对于有操作系统的内核上,可以选择多进程或多线程来完成

2> 如果没有操作系统,实现多任务同时执行就需要使用其他技术了:IO多路复用

3> 无需创建新的进程或者线程,能够减少系统资源的开销,减少上下文切换的次数

4> 原理图

1.18号网络_第1张图片

select

        #include
        #include
       #include
       #include

       int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
       功能:阻塞函数,检测管理的文件描述符集合,直到该集合中有一个或多个文件描述符事件发生,并解除阻塞
       参数1:要检测的文件描述符集合中的最大文件描述符 + 1
       参数2、3、4:分别表示读文件描述符集合、写文件描述符集合、异常文件描述符集合,由于写操作也可以转换为读操作,所以,对于小的程序而言,只需要一个集合即可 ,不使用的集合填NULL即可
       参数5:超时时间,给定一个阻塞时间,如果时间到了,就自动解除select的阻塞,NULL表示永久阻塞
            struct timeval {
               long    tv_sec;         /* seconds */      秒数
               long    tv_usec;        /* microseconds */  微秒
           };
        返回值:>0:本次成功触发解除阻塞的文件描述符个数,当解除select阻塞室,文件描述符集合中只剩下本次触发解除阻塞的文件描述符了
                =0:表示没有任何事件产生,但是超时
                =-1:失败返回-1并置位错误码
        
         
       有关集合的操作函数:   

       void FD_CLR(int fd, fd_set *set);         //将文件描述符fd从集合set中清除 
       int  FD_ISSET(int fd, fd_set *set);       //判断文件描述符fd是否存在于集合set中
       void FD_SET(int fd, fd_set *set);         //将文件描述符fd放入集合set中
       void FD_ZERO(fd_set *set);                //将文件描述符集合清空

使用IO多路复用完成TCP并发服务器

poll实现多路复用

         #include

       int poll(struct pollfd *fds, nfds_t nfds, int timeout);
功能:阻塞等待文件描述符结构体数组中是否有事件产生,如果有事件产生,则解除阻塞
参数1:文件描述符结构体数组
        struct pollfd {
               int   fd;         /* file descriptor */       要检测的文件描述符
               short events;     /* requested events */      要等待的事件
               short revents;    /* returned events */        触发的事件,用于返回结果
           };
           关于events和revents的值:
           POLLIN:读事件
           POLLOUT:写事件
           POLLERR:错误,只在revents中收到,不能设置到events中

            
             
参数2:参数1数组的长度,也就是检测文件描述符的个数
参数3:超时时间,以毫秒为单位
        >0:表示设置的超时时间
        =0:非阻塞
        =-1:表示阻塞
返回值:成功返回触发本次接触阻塞的文件描述符的个数
        0:表示超时
        -1:表示失败,并置位错误码

你可能感兴趣的:(笔记)