Linux系统编程:网络服务器

1.网络服务器

(1)单循环服务器通常指一种非常简单的网络服务器,它使用单个线程不断地接收和处理来自客户端的请求。单循环服务器适合处理少量的并发连接,但随着连接数的增加,它会导致性能问题,因为单个线程无法高效地处理大量的并发连接。

(2)并发网络服务器使用多个线程或进程来处理多个客户端连接,以提高服务器的性能和并发能力。

2.并发网络服务器可分为多进程,多线程以及IO多路复用

多进程并发服务器:

优点:每个进程都拥有独立的内存空间和系统资源,进程间不会互相干扰,提高了系统的稳定性,在一个进程崩溃时,其他进程不会受到影响。

缺点:每个进程都需要消耗一定的系统资源,包括内存和CPU时间,进程间的通信和切换比线程间的通信和切换更加耗时,效率较低。

多线程并发服务器:

优点:线程间共享同一进程的内存空间,使得多线程在并发处理上具有更高的效率,相比于多进程,多线程能够更节省资源,特别是内存资源。
缺点:

多个线程可能会同时访问共享资源,可能会导致资源侵占,还有可能导致死锁。

IO多路复用并发服务器:

IO多路复用是多个IO对一个进程多次访问

(1)select:
      1. 创建文件描述符集合   fd_set
      2. 添加文件描述符到集合中 void FD_SET(int fd, fd_set *set);
      3. 通知内核开始监测        select
      4. 根据返回的结果做对应的操作(对io读、写操作)

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
       功能:监测多路IO
       参数:
                 nfds : 关注的文件描述符中的最大值+1   
                  readfds:关注的读事件的文件描述符集合
                 writefds:关注的写事件的文件描述符结合
                 exceptfds:其他  异常
                 timeout : 超时时间,如果不设置:NULL
      返回值:
              成功:返回到达事件的个数
               失败:-1
              设置了超时时间:超时时间到达但没有事件,返回0
     宏:

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

优缺点:
            1.select监听文件描述符最大个数为1024    (数组)     O(n)
            2.select监听的文件描述符集合在用户层,需要应用层和内核层互相传递数据
            3.select需要循环遍历一次才能找到产生的事件
            4.select只能工作在水平触发模式(低速模式)无法工作在边沿触发模式(高速模式)
 

(2)epoll:监控多路IO

      1. 创建文件描述符集合                  int epoll_create(int size);
      2. 添加文件描述符到集合中           epoll_ctl()
      3. 通知内核开始监测                     epoll_wait()
      4. 根据返回的结果做对应的操作(对io读、写操作)
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 :操作的文件描述符
         event :文件描述符所对应的事件

        共用体: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 */
           };

          event : EPOLLIN :  读操作
                       EPOLLOUT : 写事件


    int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
   功能:监测IO事件
   参数:
             epfd : 文件描述符集合句柄
             events : 保存到达事件的结合的首地址
             maxevents : 监测时事件的个数
            timeout:超时时间
                  -1  :不设置超时时间

返回值:
          成功:返回到达事件的个数
          失败:-1
          设置超时:超时时间到达返回0            
         优点:
            1.epoll创建内核事件表,不受到文件描述符上限限制    (红黑树)  O(logn)        
            2.epoll监听的事件表在内核中,直接在内核中监测事件效率高
            3.epoll会直接获得产生事件的文件描述符的信息,而不需要遍历检测 
            4.epoll既能工作在水平触发模式,也能工作在边沿触发模式

3.常见的IO模型:

(1) 阻塞IO:

应用程序发起一个IO请求后,会一直阻塞等待操作完成,直到数据准备好或者超时才返回结果。这种模型在IO操作期间会阻塞当前线程,无法执行其他任务,适用于连接数较少的场景。

(2)非阻塞IO:

应用程序发起一个IO请求后会立即返回,无需等待操作完成。应用程序需要不断轮询或者使用事件通知来检查操作是否完成。这种模型适用于需要处理多个连接或者连接数较多的场景,但效率不高。

(3)信号驱动IO:

应用程序通过向内核注册信号处理函数来处理IO事件。当IO操作完成时,内核会发送一个信号通知应用程序,然后由应用程序在信号处理函数中处理该事件。这种模型相比阻塞IO和非阻塞IO更为灵活,但信号队列在Linux中有限制,可能导致无法读取数据。

(4)IO多路复用:

IO多路复用模型使用操作系统提供的select、poll或epoll等多路复用机制,允许应用程序同时监视多个IO事件。应用程序可以将多个IO请求注册到一个多路复用器上,然后通过轮询或者阻塞等待多路复用器通知事件的发生。这种模型适用于需要同时处理多个连接的场景,提高了系统的并发性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值