真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

linux要用select的原因是什么

本篇內(nèi)容介紹了“l(fā)inux要用select的原因是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出正鑲白免費(fèi)做網(wǎng)站回饋大家。

因?yàn)閟elect可以使開發(fā)者在同時(shí)等待多個(gè)文件緩沖區(qū),可減少IO等待的時(shí)間,能夠提高進(jìn)程的IO效率。select()函數(shù)是IO多路復(fù)用的函數(shù),允許程序監(jiān)視多個(gè)文件描述符,等待所監(jiān)視的一個(gè)或者多個(gè)文件描述符變?yōu)椤皽?zhǔn)備好”的狀態(tài);所謂的”準(zhǔn)備好“狀態(tài)是指:文件描述符不再是阻塞狀態(tài),可以用于某類IO操作了,包括可讀,可寫,發(fā)生異常三種。

select是一個(gè)計(jì)算機(jī)函數(shù),位于頭文件#include 。該函數(shù)用于監(jiān)視文件描述符的變化情況——讀寫或是異常。

1. select函數(shù)介紹

select函數(shù)是IO多路復(fù)用的函數(shù),它主要的功能是用來(lái)等文件描述符中的事件是否就緒,select可以使我們?cè)谕瑫r(shí)等待多個(gè)文件緩沖區(qū) ,減少IO等待的時(shí)間,能夠提高進(jìn)程的IO效率。

select()函數(shù)允許程序監(jiān)視多個(gè)文件描述符,等待所監(jiān)視的一個(gè)或者多個(gè)文件描述符變?yōu)椤皽?zhǔn)備好”的狀態(tài)。所謂的”準(zhǔn)備好“狀態(tài)是指:文件描述符不再是阻塞狀態(tài),可以用于某類IO操作了,包括可讀,可寫,發(fā)生異常三種

2. select函數(shù)參數(shù)的介紹

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

ndfs

等待的文件描述符的最大值+1,例如:應(yīng)用進(jìn)程想要去等待文件描述符3,5,8的事件,則

nfds=max(3,5,8)+1;

fd_set類型

readfds和writefds,exceptfds的類型都是fd_set,那么fd_set類型是什么呢?

  • fd_set類型本質(zhì)是一個(gè)位圖,位圖的位置 表示 相對(duì)應(yīng)的文件描述符,內(nèi)容表示該文件描述符是否有效,1代表該位置的文件描述符有效,0則表示該位置的文件描述符無(wú)效。

  • 如果將文件描述符2,3設(shè)置位圖當(dāng)中,則位圖表示的是為1100。

  • fd_set的上限是1024個(gè)文件描述符。

readfds

  • readfds是 等待讀事件的文件描述符集合,.如果不關(guān)心讀事件(緩沖區(qū)有數(shù)據(jù)),則可以傳NULL值。

  • 應(yīng)用進(jìn)程和內(nèi)核都可以設(shè)置readfds,應(yīng)用進(jìn)程設(shè)置readfds是為了通知內(nèi)核去等待readfds中的文件描述符的讀事件.而 內(nèi)核設(shè)置readfds是為了告訴應(yīng)用進(jìn)程哪些讀事件生效

linux要用select的原因是什么

writefds

與readfds類似,writefds是等待寫事件(緩沖區(qū)中是否有空間)的集合,如果不關(guān)心寫事件,則可以傳值NULL。

exceptfds

如果內(nèi)核等待相應(yīng)的文件描述符發(fā)生異常,則將失敗的文件描述符設(shè)置進(jìn)exceptfds中,如果不關(guān)心錯(cuò)誤事件,可以傳值NULL。

timeout

設(shè)置select在內(nèi)核中阻塞的時(shí)間,如果想要設(shè)置為非阻塞,則設(shè)置為NULL。如果想讓select阻塞5秒,則將創(chuàng)建一個(gè)struct timeval time={5,0};

其中struct timeval的結(jié)構(gòu)體類型是:

           struct timeval {
               long    tv_sec;         /* seconds */
               long    tv_usec;        /* microseconds */
           };

返回值

  • 如果沒(méi)有文件描述符就緒就返回0;

  • 如果調(diào)用失敗返回-1;

  • 如果timeout中中readfds中有事件發(fā)生,則返回timeout剩下的時(shí)間。

3.select的工作流程

應(yīng)用進(jìn)程內(nèi)核都需要從readfds和writefds獲取信息,其中,內(nèi)核需要從readfds和writefds知道哪些文件描述符需要等待,應(yīng)用進(jìn)程需要從readfds和writefds中知道哪些文件描述符的事件就緒.

linux要用select的原因是什么

如果我們要不斷輪詢等待文件描述符,則應(yīng)用進(jìn)程需要不斷的重新設(shè)置readfds和writefds,因?yàn)槊恳淮握{(diào)用select,內(nèi)核會(huì)修改readfds和writefds,所以我們需要在 應(yīng)用程序設(shè)置一個(gè)數(shù)組來(lái)保存程序需要等待的文件描述符,保證調(diào)用 select 的時(shí)候readfds 和 writefds中的將如下:

linux要用select的原因是什么

4.Select服務(wù)器

如果是一個(gè)select服務(wù)器進(jìn)程,則服務(wù)器進(jìn)程會(huì)不斷的接收有新鏈接,每個(gè)鏈接對(duì)應(yīng)一個(gè)文件描述符,如果想要我們的服務(wù)器能夠同時(shí)等待多個(gè)鏈接的數(shù)據(jù)的到來(lái),我們監(jiān)聽套接字listen_sock讀取新鏈接的時(shí)候,我們需要將新鏈接的文件描述符保存到read_arrys數(shù)組中,下次輪詢檢測(cè)的就會(huì)將新鏈接的文件描述符設(shè)置進(jìn)readfds中,如果有鏈接關(guān)閉,則將相對(duì)應(yīng)的文件描述符從read_arrys數(shù)組中拿走。

一張圖看懂select服務(wù)器:

linux要用select的原因是什么

簡(jiǎn)易版的select服務(wù)器:

server.hpp文件:

#pragma once                                                                                                           
  #include    
  #include    
  #include    
  #include    
  #include    
  using std::cout;    
  using std::endl;    
  #define BACKLOG 5    
      
  namespace sjp{    
    class server{    
      public:    
      static int Socket(){    
        int sock=socket(AF_INET,SOCK_STREAM,0);    
        if(sock>0)    
        return sock;    
        if(sock<0)    
          exit(-1);    
W>    }    
      
      static bool Bind(int sockfd,short int port){    
        struct sockaddr_in lock;    
        memset(&lock,'\0',sizeof(lock));    
        lock.sin_family=AF_INET;    
        lock.sin_port=htons(port);    
        lock.sin_addr.s_addr=INADDR_ANY;    
        if(bind(sockfd,(struct sockaddr*)&lock,(socklen_t)sizeof(lock))<0){    
                  exit(-2);    
        }    
        return true;    
      }    

     static bool Listen(int sockfd){
        if(listen(sockfd,BACKLOG)<0){
          exit(-3);
        }
        return true;
      }
    };
  }

select_server.hpp文件

#pragma once                                                                                                           
  #include
  #include"server.hpp"
  #include
  #include
  
  namespace Select{
    class select_server{
      private:
        int listen_sock;//監(jiān)聽套接字    
        int port;    
          
      public:    
        select_server(int _port):port(_port){}    
      
        //初始化select_server服務(wù)器    
        void InitServer(){    
          listen_sock=sjp::server::Socket();    
          sjp::server::Bind(listen_sock,port);    
          sjp::server::Listen(listen_sock);    
        }    
      
      
        void Run(){    
          std::vector readfds_arry(1024,-1);//readfds_arry保存讀事件的文件描述符    
          readfds_arry[0]=listen_sock;//將監(jiān)聽套接字保存進(jìn)readfds_arry數(shù)組中    
          fd_set readfds;    
          while(1){    
          FD_ZERO(&readfds);    
          int nfds=0;    
          //將read_arry數(shù)組中的文件描述符設(shè)置進(jìn)程readfds_arry位圖中    
          for(int i=0;i<1024;i++)    
          {    
            if(readfds_arry[i]!=-1){    
            FD_SET(readfds_arry[i],&readfds);    
           if(nfds& readfds_arry,fd_set readfds){
W>        for(int i=0;i& fds_arry,int fd){
W>        for(int i=0;i

select_server.cc文件

#include"select_server.hpp"    
    
int main(int argv,char* argc[]){    
  if(argv!=2){    
    cout<<"./selectserver port"<InitServer();                                             
  sl->Run();                                                                                                   
}

測(cè)試:

linux要用select的原因是什么

linux要用select的原因是什么

5.Select的缺陷

  • 由于fd_set的上限是1024,所以select能等待的讀事件的文件描述符和寫事件的文件描述是有上限的,如果作為一個(gè)大型服務(wù)器,能夠同時(shí)鏈接的客戶端是遠(yuǎn)遠(yuǎn)不夠的。

  • 每次應(yīng)用進(jìn)程調(diào)用一次select之前,都需要重新設(shè)定writefds和readfds,如果進(jìn)行輪詢調(diào)用select,這對(duì)影響cpu效率。

  • 內(nèi)核每一次等待文件描述符 都會(huì)重新掃描所有readfds或者writefds中的所有文件描述符,如果有較多的文件描述符,則會(huì)影響效率。

“l(fā)inux要用select的原因是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


名稱欄目:linux要用select的原因是什么
新聞來(lái)源:http://weahome.cn/article/ggpood.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部