服务器并发模型

服务器:

单循环服务器:服务器在同一时刻只能响应一个客户端的请求

并发服务器模型:服务器在同一时刻可以响应多个客户端的请求
 

UDP:无连接
    
    TCP:有连接
    1.多进程
        资源空间消耗大
        效率低

    2.多线程
        相对进程资源消耗小
        效率较高
    3.IO多路复用:
      为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,
      使进程不阻塞于某个特定的 I/O 系统调用。
     优势:
        系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程。

多进程并发服务器

 

多线程并发服务器 

Linux系统IO模型:

1.阻塞IO

scnaf
        getchar
        fgets
        gets
        
        read
        recv
        recvfrom
        1.可以实现多任务同步(多个事件相互影响)
        2.可以节省CPU资源开销,提高执行效率
 

2.非阻塞IO

        1. 获取文件描述符属性
            fcntl---------flag      0
        2. 为文件描述符添加非阻塞属性
        3. 设置文件描述符属性
            fcntl

        增加非阻塞属性
        flag = fcntl(0,F_GETFL);
        flag = flag | O_NONBLOCK;
        fcntl(0,F_SETFL,flag);
    
        1.可以访问多个IO事件
        2.配合轮询操作,浪费CPU资源


3.信号驱动IO

        1.实现异步IO操作,节省CPU开销
        2.只能针对比较少的IO事件
        
        
        1)为IO设备增加信号驱动属性
            O_ASYNC
        2)关联SIGIO信号到对应进程
            fcntl(fd, F_SETOWN, getpid());
        3) 注册SIGIO处理函数
            signal

4.多路复用IO

        1.select
         缺点:
            1.select监听文件描述符最大个数为1024    (数组)    
            2.select监听的文件描述符集合在用户层,需要应用层和内核层互相传递数据
            3.select需要循环遍历一次才能找到产生的事件
            4.select只能工作在水平触发模式(低速模式)无法工作在边沿触发模式(高速模式)
            
       2.poll
         缺点:
            1.poll监测文件描述符不受上限限制  (链表)
            2.poll监听的文件描述符集合在用户层,需要内核层向用户层传递数据
            3.poll需要循环遍历一次才能找到产生的事件
            4.poll只能工作在水平触发模式(低速模式)无法工作在边沿触发模式(高速模式)
            
       3.epoll
         优点:
            1.epoll创建内核事件表,不受到文件描述符上限限制    (红黑树)        
            2.epoll监听的事件表在内核中,直接在内核中监测事件效率高
            3.epoll会直接获得产生事件的文件描述符的信息,而不需要遍历检测 
            4.epoll既能工作在水平触发模式,也能工作在边沿触发模式
        
        操作方法:
        1)创建文件描述符集合
        2)添加关注的文件描述符到集合中
        3)监测IO事件

select

 int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
      功能:
        监听文件描述符集合
      参数:
        nfds:监测的文件描述符上限值(最大文件描述符的值+1)
        readfds:读文件描述符集合
        writefds:写文件描述符集合
        exceptfds:异常条件的描述符集合
        timeout:设置超时时间
            NULL:一直等待
            
      返回值:
        成功返回产生事件文件描述符个数
        失败返回-1 
        定时时间到达仍没有事件产生返回0 
    
       void FD_CLR(int fd, fd_set *set);
       将fd从文件描述符集合中清除
       
       int  FD_ISSET(int fd, fd_set *set);
       判断文件描述符fd是否仍在文件描述符集合中
       
       void FD_SET(int fd, fd_set *set);
       将fd加入文件描述符集合中
        
       void FD_ZERO(fd_set *set);
       文件描述符集合清0 

fcntl

int fcntl(int fd, int cmd, ... /* arg */ );
      功能:
        设置文件描述符属性 
      参数:
        fd:文件描述符 
        cmd:F_GETFL        获得文件描述符属性
            F_SETFL        设置文件描述符属性 
      返回值:
        F_GETFL:
            成功返回获得的属性
            失败返回-1 
        F_SETFL:
            成功返回0 
            失败返回-1 

        O_NONBLOCK   非阻塞
        O_ASYNC      异步方式
        
        修改IO属性:
        1)获取原有属性
        2)增加新的属性
        3)设置新的属性

注意:文件属性是直接设置完成的,设置完成后就算去掉代码行,依旧会保留上一次更改设置。

 

 select内核监听,当对应的监听内容触发后执行,大大减小了cpu的开支,以扩大服务器的容量。

使用select创建一个无进程和线程的io多路复用服务器,对多用户进行连接。

 poll

  int poll(struct pollfd *fds, nfds_t nfds, int timeout);
      功能:
        监听文件描述符集合中的事件
      参数:
        fds:文件描述符集合事件数组首地址
        nfds:事件个数
        timeout:超时时间
      返回值:
        成功返回产生事件的文件描述符个数
        失败返回-1 
        超时时间到达仍没有产生事件返回0 
    
    struct pollfd {
       int   fd;         /* file descriptor */
       short events;     /* requested events */
       short revents;    /* returned events */
    };

epoll

    1)epoll_create 创建epoll文件描述符集合
    2)epoll_ctl  添加关注的文件描述符
    3)epoll_wait 监控io事件
    4)epoll_ctl  从事件集合中删除完成的文件描述符
 

epoll_create

  int epoll_create(int size);
      功能:
        创建一个监听事件表(内核中)
      参数:
        size:监听事件最大个数
      返回值:
        成功返回非负值:表示epoll事件表对象(句柄)
        失败返回-1 
 

epoll_ctl

 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
      功能:
        在监听事件表中新增一个事件
      参数:
        epfd:事件表文件描述符 
         op:EPOLL_CTL_ADD                新增事件
           EPOLL_CTL_MOD        修改事件 
           EPOLL_CTL_DEL                删除事件
        fd:文件描述符 
        events:事件相关结构体
      返回值:
        成功返回0 
        失败返回-1 
            
        typedef union epoll_data {
           void        *ptr;
           int          fd;
           uint32_t     u32;
           uint64_t     u64;
        } epoll_data_t;

        struct epoll_event {
           uint32_t     events;      /* Epoll events */
           epoll_data_t data;        /* User data variable */
        };

     events:
        EPOLLIN        读事件
        EPOLLOUT    写事件
        
        
        EPOLLET        边沿触发    
        LT            水平触发
 

epoll_wait

  int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
      功能:
        监听事件表中的事件,并将产生的事件存放到结构体数组中
      参数:
        epfd:事件表文件描述符
        events:存放结果事件结构体数组空间首地址 
        maxevents:最多存放事件个数
        timeout:超时时间
            -1:阻塞等待直到有事件发生 
      返回值:
        成功返回产生事件个数
        失败返回-1 
        超时时间到达没有事件发生返回0 


 epoll的服务器并行模型。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值