Inhaltsverzeichnis
1. Einführung in die Auswahlfunktion
Maximalwert der wartenden Dateideskriptoren +1, zum Beispiel : Wenn der Anwendungsprozess auf Ereignisse der Dateideskriptoren 3, 5, 8 warten möchte, dann
Die Typen von Readfds, Writefds und Exceptfds sind alle fd_set. Was ist also der Typ fd_set?
Der Kernel setzt readfds auf , um dem Anwendungsprozess mitzuteilen, welche Leseereignisse wirksam werden
timeout
#🎜🎜 # Wenn der Aufruf fehlschlägt, wird -1 zurückgegeben;
3.Workflow auswählen
Stellen Sie sicher, dass beim Aufruf von select die Werte in readfds und writefds wie folgt lauten:
4.Select服务器
5.Select的缺陷
Heim Betrieb und Instandhaltung Betrieb und Wartung von Linux Was ist der Grund, warum Linux select verwendet?

Was ist der Grund, warum Linux select verwendet?

May 19, 2023 pm 03:07 PM
linux select

Mit der Auswahlfunktion können Entwickler gleichzeitig auf mehrere Dateipuffer warten, wodurch die E/A-Wartezeit verkürzt und die E/A-Effizienz des Prozesses verbessert wird. Die Funktion select() ist eine E/A-Multiplexfunktion, die es dem Programm ermöglicht, mehrere Dateideskriptoren zu überwachen und darauf zu warten, dass einer oder mehrere der überwachten Dateideskriptoren „bereit“ werden. Bezieht sich auf: die Datei Der Deskriptor ist nicht mehr blockiert und kann für bestimmte Arten von E/A-Vorgängen verwendet werden, einschließlich lesbarer, beschreibbarer und Ausnahmen.

#includeDie Header-Datei enthält die Select-Funktion, die im Computer aufgerufen werden kann. Diese Funktion wird verwendet, um Dateideskriptoränderungen zu überwachen – Lesen, Schreiben oder Ausnahmen.

1. Einführung in die Auswahlfunktion

Die Hauptfunktion besteht darin, auf die Dateibeschreibung zu warten Wenn das Symbol bereit ist, können wir durch Auswählen gleichzeitig auf mehrere Dateipuffer warten, die E/A-Wartezeit verkürzen und die E/A-Effizienz des Prozesses verbessern.

select()-Funktion ermöglicht es dem Programm, mehrere Dateideskriptoren zu überwachen und darauf zu warten, dass einer oder mehrere der überwachten Dateideskriptoren „bereit“ werden. Der sogenannte „Bereit“-Zustand bedeutet, dass der Dateideskriptor nicht mehr blockiert ist und für bestimmte Arten von E/A-Vorgängen verwendet werden kann, einschließlich lesbarer, beschreibbarer und Ausnahmevorfälle

#🎜🎜 ##🎜 🎜#2. Einführung in die Auswahl von Funktionsparametern

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
Nach dem Login kopieren

ndfs

Maximalwert der wartenden Dateideskriptoren +1, zum Beispiel : Wenn der Anwendungsprozess auf Ereignisse der Dateideskriptoren 3, 5, 8 warten möchte, dann

nfds=max(3,5,8)+1;
Nach dem Login kopieren

fd_set type

Die Typen von Readfds, Writefds und Exceptfds sind alle fd_set. Was ist also der Typ fd_set?

  • Der Typ fd_set ist im Wesentlichen eine Bitmap

    Die Position der Bitmap repräsentiert den entsprechenden Dateideskriptor und der Inhalt repräsentiert den Dateideskriptor . Ob es gültig ist, 1 bedeutet, dass der Dateideskriptor an diesem Speicherort gültig ist, 0 bedeutet, dass der Dateideskriptor an diesem Speicherort ungültig ist.

  • Wenn die Dateideskriptoren 2 und 3 in der Bitmap festgelegt sind, stellt die Bitmap 1100 dar.
  • Die Obergrenze von fd_set beträgt 1024 Dateideskriptoren. #🎜🎜 ##### 🎜🎜 ## 🎜🎜 ## 🎜🎜#Readfds#🎜🎜 ## 🎜🎜 ## 🎜🎜 ## 🎜🎜#Readfds wartet darauf, das Ereignis zu lesen Der Dateideskriptor set
  • ,. Wenn Ihnen das Leseereignis egal ist (der Puffer enthält Daten), können Sie einen NULL-Wert übergeben.

Sowohl der Anwendungsprozess als auch der Kernel können readfds festlegen, um den Kernel zu benachrichtigen, auf das Leseereignis des Dateideskriptors in readfds zu warten

Der Kernel setzt readfds auf , um dem Anwendungsprozess mitzuteilen, welche Leseereignisse wirksam werden

  • # 🎜🎜##🎜 🎜#

    writefds
  • Ähnlich wie readfds ist writefds eine Sammlung, die auf Schreibereignisse wartet (unabhängig davon, ob Platz im Puffer vorhanden ist). Wenn Sie sich nicht für Schreibereignisse interessieren, können Sie den Wert NULL übergeben. exclusivefds

  • Wenn
eine Ausnahme

auftritt, während der Kernel auf den entsprechenden Dateideskriptor wartet, dann # 🎜🎜# wird Der fehlgeschlagene Dateideskriptor wird in „exclusedfds“ gesetzt Was ist der Grund, warum Linux select verwendet? Wenn Sie sich nicht für Fehlerereignisse interessieren, können Sie den Wert NULL übergeben.

timeout

Stellen Sie die Zeit ein, zu der ausgewählte Blöcke im Kernel eingestellt werden sollen . Wenn Sie eine Blockierung für 5 Sekunden auswählen möchten, erstellen Sie eine

struct timeval time={5,0}

;wobei der Strukturtyp von struct timeval ist: # 🎜🎜 #
           struct timeval {
               long    tv_sec;         /* seconds */
               long    tv_usec;        /* microseconds */
           };
Nach dem Login kopieren

Rückgabewert

Gibt 0 zurück, wenn kein Dateideskriptor bereit ist;

#🎜🎜 # Wenn der Aufruf fehlschlägt, wird -1 zurückgegeben;

Wenn ein Ereignis in readfds im Timeout auftritt, beträgt die verbleibende Zeit des Timeouts zurückgegeben.

3.Workflow auswählen

  • Bewerbungsprozess

    und# 🎜🎜 #Kernel

    Beide müssen Informationen von readfds und writefds erhalten. Dazu muss der Kernel wissen, welche Dateideskriptoren von readfds und writefds warten müssen, und der Anwendungsprozess muss wissen, welche Dateideskriptorereignisse von readfds bereit sind und writefds.
  • Wenn wir kontinuierlich Dateideskriptoren abfragen und warten möchten, muss der Anwendungsprozess readfds und writefds ständig zurücksetzen, da jedes Mal ausgewählt wird aufgerufen wird, werden die Readfds und Writefds des Kernels geändert, daher müssen wir in der
  • Anwendung

  • ein Array
festlegen, um die Dateideskriptoren zu speichern, die das Programm benötigt warten,

Stellen Sie sicher, dass beim Aufruf von select die Werte in readfds und writefds wie folgt lauten:

4.Select服务器

如果是一个select服务器进程,则服务器进程会不断的接收有新链接,每个链接对应一个文件描述符,如果想要我们的服务器能够同时等待多个链接的数据的到来,我们监听套接字listen_sock读取新链接的时候,我们需要将新链接的文件描述符保存到read_arrys数组中,下次轮询检测的就会将新链接的文件描述符设置进readfds中,如果有链接关闭,则将相对应的文件描述符从read_arrys数组中拿走。

一张图看懂select服务器:

Was ist der Grund, warum Linux select verwendet?

简易版的select服务器:

server.hpp文件:

#pragma once                                                                                                           
  #include<iostream>    
  #include<sys/socket.h>    
  #include<sys/types.h>    
  #include<netinet/in.h>    
  #include<string.h>    
  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,&#39;\0&#39;,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;
      }
    };
  }
Nach dem Login kopieren

select_server.hpp文件

#pragma once                                                                                                           
  #include<vector>
  #include"server.hpp"
  #include<unistd.h>
  #include<time.h>
  
  namespace Select{
    class select_server{
      private:
        int listen_sock;//监听套接字    
        int port;    
          
      public:    
        select_server(int _port):port(_port){}    
      
        //初始化select_server服务器    
        void InitServer(){    
          listen_sock=sjp::server::Socket();    
          sjp::server::Bind(listen_sock,port);    
          sjp::server::Listen(listen_sock);    
        }    
      
      
        void Run(){    
          std::vector<int> readfds_arry(1024,-1);//readfds_arry保存读事件的文件描述符    
          readfds_arry[0]=listen_sock;//将监听套接字保存进readfds_arry数组中    
          fd_set readfds;    
          while(1){    
          FD_ZERO(&readfds);    
          int nfds=0;    
          //将read_arry数组中的文件描述符设置进程readfds_arry位图中    
          for(int i=0;i<1024;i++)    
          {    
            if(readfds_arry[i]!=-1){    
            FD_SET(readfds_arry[i],&readfds);    
           if(nfds<readfds_arry[i]){
              nfds=readfds_arry[i];
            }
            }
          }
  
          //调用select对readfds中的文件描述符进行等待数据
          switch(select(nfds+1,&readfds,NULL,NULL,NULL)){
            case 0:
              //没有一个文件描述符的读事件就绪
              cout<<"select timeout"<<endl;
              break;
            case -1:
              //select失败
              cout<<"select error"<<endl;
            default:
              {
              //有读事件发生
                Soluation(readfds_arry,readfds);
                break;
              }
          }           
          }
        }
                                                                                                                         
        void Soluation(std::vector<int>& readfds_arry,fd_set readfds){
W>        for(int i=0;i<readfds_arry.size();i++){
            if(FD_ISSET(readfds_arry[i],&readfds))
            {
              if(readfds_arry[i]==listen_sock){
                //有新链接到来
                struct sockaddr peer;
                socklen_t len;                                                                                           
                int newfd=accept(listen_sock,&peer,&len);
                cout<<newfd<<endl;
                //将新链接设置进readfds_arry数组中
                AddfdsArry(readfds_arry,newfd);
              }
              else{
                //其他事件就绪
                char str[1024];
                int sz=recv(readfds_arry[i],&str,sizeof(str),MSG_DONTWAIT);
                switch(sz){
                  case -1:
                    //读取失败
                    cout<<readfds_arry[i]<<": recv error"<<endl;
                    break;
                  case 0:
                    //对端关闭
                    readfds_arry[i]=-1;
                    cout<<"peer close"<<endl;
                    break;
                  default:
                    str[sz]=&#39;\0&#39;;
                    cout<<str<<endl;
                    break;
                }
              }
            }
          }
        }

        void AddfdsArry(std::vector<int>& fds_arry,int fd){
W>        for(int i=0;i<fds_arry.size();i++){
            if(fds_arry[i]==-1){
              fds_arry[i]=fd;
              break;
            }
          }
        }
    };
  }
Nach dem Login kopieren

select_server.cc文件

#include"select_server.hpp"    
    
int main(int argv,char* argc[]){    
  if(argv!=2){    
    cout<<"./selectserver port"<<endl;    
    exit(-4);    
  }    
                                                                                                                         
  int port=atoi(argc[1]);//端口号
  Select::select_server* sl=new Select::select_server(port);    
  sl->InitServer();                                             
  sl->Run();                                                                                                   
}
Nach dem Login kopieren

测试:

Was ist der Grund, warum Linux select verwendet?

Was ist der Grund, warum Linux select verwendet?

5.Select的缺陷

  • 由于fd_set的上限是1024,所以select能等待的读事件的文件描述符和写事件的文件描述是有上限的,如果作为一个大型服务器,能够同时链接的客户端是远远不够的。

  • 每次应用进程调用一次select之前,都需要重新设定writefds和readfds,如果进行轮询调用select,这对影响cpu效率。

  • 内核每一次等待文件描述符 都会重新扫描所有readfds或者writefds中的所有文件描述符,如果有较多的文件描述符,则会影响效率。

Das obige ist der detaillierte Inhalt vonWas ist der Grund, warum Linux select verwendet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Ich kann mich nicht als Stamm bei MySQL anmelden Ich kann mich nicht als Stamm bei MySQL anmelden Apr 08, 2025 pm 04:54 PM

Die Hauptgründe, warum Sie sich bei MySQL nicht als Root anmelden können, sind Berechtigungsprobleme, Konfigurationsdateifehler, Kennwort inkonsistent, Socket -Dateiprobleme oder Firewall -Interception. Die Lösung umfasst: Überprüfen Sie, ob der Parameter Bind-Address in der Konfigurationsdatei korrekt konfiguriert ist. Überprüfen Sie, ob die Root -Benutzerberechtigungen geändert oder gelöscht und zurückgesetzt wurden. Stellen Sie sicher, dass das Passwort korrekt ist, einschließlich Fall- und Sonderzeichen. Überprüfen Sie die Einstellungen und Pfade der Socket -Dateiberechtigte. Überprüfen Sie, ob die Firewall Verbindungen zum MySQL -Server blockiert.

Lösungen für die von MySQL auf einer bestimmten Systemversion gemeldeten Fehler Lösungen für die von MySQL auf einer bestimmten Systemversion gemeldeten Fehler Apr 08, 2025 am 11:54 AM

Die Lösung für den MySQL -Installationsfehler ist: 1. Überprüfen Sie die Systemumgebung sorgfältig, um sicherzustellen, dass die Anforderungen der MySQL -Abhängigkeitsbibliothek erfüllt werden. Unterschiedliche Betriebssysteme und Versionsanforderungen sind unterschiedlich. 2. Lesen Sie die Fehlermeldung sorgfältig durch und ergreifen Sie entsprechende Maßnahmen gemäß den Eingabeaufforderungen (z. B. fehlende Bibliotheksdateien oder unzureichende Berechtigungen), z. B. die Installation von Abhängigkeiten oder die Verwendung von SUDO -Befehlen; 3. Versuchen Sie bei Bedarf, den Quellcode zu installieren und das Kompilierungsprotokoll sorgfältig zu überprüfen. Dies erfordert jedoch eine bestimmte Menge an Linux -Kenntnissen und -erfahrung. Der Schlüssel zur letztendlichen Lösung des Problems besteht darin, die Systemumgebung und Fehlerinformationen sorgfältig zu überprüfen und auf die offiziellen Dokumente zu verweisen.

Wie man MySQL löst, kann nicht gestartet werden Wie man MySQL löst, kann nicht gestartet werden Apr 08, 2025 pm 02:21 PM

Es gibt viele Gründe, warum MySQL Startup fehlschlägt und durch Überprüfung des Fehlerprotokolls diagnostiziert werden kann. Zu den allgemeinen Ursachen gehören Portkonflikte (prüfen Portbelegung und Änderung der Konfiguration), Berechtigungsprobleme (Überprüfen Sie den Dienst Ausführen von Benutzerberechtigungen), Konfigurationsdateifehler (Überprüfung der Parametereinstellungen), Datenverzeichniskorruption (Wiederherstellung von Daten oder Wiederaufbautabellenraum), InnoDB-Tabellenraumprobleme (prüfen IBDATA1-Dateien), Plug-in-Ladeversagen (Überprüfen Sie Fehlerprotokolle). Wenn Sie Probleme lösen, sollten Sie sie anhand des Fehlerprotokolls analysieren, die Hauptursache des Problems finden und die Gewohnheit entwickeln, Daten regelmäßig zu unterstützen, um Probleme zu verhindern und zu lösen.

Kann MySQL auf Android laufen? Kann MySQL auf Android laufen? Apr 08, 2025 pm 05:03 PM

MySQL kann nicht direkt auf Android ausgeführt werden, kann jedoch indirekt mit den folgenden Methoden implementiert werden: Die Verwendung der Leichtgewichtsdatenbank SQLite, die auf dem Android -System basiert, benötigt keinen separaten Server und verfügt über eine kleine Ressourcennutzung, die für Anwendungen für Mobilgeräte sehr geeignet ist. Stellen Sie sich remote eine Verbindung zum MySQL -Server her und stellen Sie über das Netzwerk zum Lesen und Schreiben von Daten über das Netzwerk eine Verbindung zur MySQL -Datenbank auf dem Remote -Server her. Es gibt jedoch Nachteile wie starke Netzwerkabhängigkeiten, Sicherheitsprobleme und Serverkosten.

Vom Terminal vom Terminal nicht auf MySQL zugreifen Vom Terminal vom Terminal nicht auf MySQL zugreifen Apr 08, 2025 pm 04:57 PM

Möglicherweise kann der Zugang zu MySQL vom Terminal nicht zugreifen: MySQL -Dienst, der nicht ausgeführt wird; Verbindungsbefehlsfehler; unzureichende Berechtigungen; Firewall blockiert die Verbindung; MySQL -Konfigurationsdateifehler.

Was nutzt Linux am meisten? Was nutzt Linux am meisten? Apr 09, 2025 am 12:02 AM

Linux wird häufig in Servern, eingebetteten Systemen und Desktopumgebungen verwendet. 1) Im Serverfeld ist Linux aufgrund seiner Stabilität und Sicherheit eine ideale Wahl für das Hosting von Websites, Datenbanken und Anwendungen geworden. 2) In eingebetteten Systemen ist Linux für seine hohe Anpassung und Effizienz beliebt. 3) In der Desktop -Umgebung bietet Linux eine Vielzahl von Desktop -Umgebungen, um den Anforderungen verschiedener Benutzer gerecht zu werden.

Überwachen Sie MySQL und Mariadb -Tröpfchen mit Prometheus Mysql Exporteur Überwachen Sie MySQL und Mariadb -Tröpfchen mit Prometheus Mysql Exporteur Apr 08, 2025 pm 02:42 PM

Eine effektive Überwachung von MySQL- und MariADB -Datenbanken ist entscheidend für die Aufrechterhaltung einer optimalen Leistung, die Identifizierung potenzieller Engpässe und die Gewährleistung der Zuverlässigkeit des Gesamtsystems. Prometheus MySQL Exporteur ist ein leistungsstarkes Tool, das detaillierte Einblicke in Datenbankmetriken bietet, die für die proaktive Verwaltung und Fehlerbehebung von entscheidender Bedeutung sind.

So lösen Sie das Problem fehlender Abhängigkeiten bei der Installation von MySQL So lösen Sie das Problem fehlender Abhängigkeiten bei der Installation von MySQL Apr 08, 2025 pm 12:00 PM

Der MySQL -Installationsfehler wird normalerweise durch das Fehlen von Abhängigkeiten verursacht. Lösung: 1. Verwenden Sie den Systempaketmanager (z. B. Linux APT, YUM oder DNF, Windows VisualC Neuverteilung), um die fehlenden Abhängigkeitsbibliotheken wie sudoaptinstalllibmysqlclient-dev zu installieren; 2. Überprüfen Sie die Fehlerinformationen sorgfältig und lösen Sie die komplexen Abhängigkeiten nacheinander. 3. Stellen Sie sicher, dass die Paket -Manager -Quelle korrekt konfiguriert ist und auf das Netzwerk zugreifen kann. 4. Laden Sie die erforderlichen Laufzeitbibliotheken herunter und installieren Sie sie für Windows. Die Entwicklung der Gewohnheit, offizielle Dokumente zu lesen und Suchmaschinen gut zu nutzen, kann effektiv Probleme lösen.

See all articles