[LINUX] Asynchrone Programmierung mit libev

libev

libev ist eine Bibliothek, die die asynchrone Verarbeitung verwaltet und auch in node.js usw. verwendet wird. Ursprünglich hatte das Unix-System einen asynchronen Prozess namens select (), der Dateideskriptoren verarbeitet. Dies begrenzte jedoch die Anzahl der zu überwachenden Dateideskriptoren. Danach wurde Unlimited Poll () entwickelt, epoll (), das poll () beschleunigte, wurde unter Linux entwickelt und KQUEUE wurde in BSD entwickelt. Und eine Bibliothek namens libev wurde entwickelt, um diese Unterschiede auszugleichen.

Installation

brew install libev

Die aktuelle Version wird an folgendem Speicherort installiert: Dieser Eintrag behandelt diesen Pfad wie er ist, ohne den Bibliothekspfad zu durchlaufen.

/usr/local/Cellar/libev/4.15/

Xcode-Einstellungen

Fügen Sie in den Build-Einstellungen des Projekts Folgendes zu "Header-Suchpfade" hinzu.

/usr/local/Cellar/libev/4.15/include/

Fügen Sie in den Build-Einstellungen des Projekts Folgendes zu "Bibliothekssuchpfade" hinzu.

/usr/local/Cellar/libev/4.15/lib/

Fügen Sie in den Build-Einstellungen des Projekts Folgendes zu "Verknüpfen" hinzu.

-lev
-ObjC
-all_load

Grundlegende Verwendung

Deklarieren Sie zuerst das Ereignisschleifenobjekt. Deklarieren Sie dann ein Überwachungsobjekt für den Ereignistyp, den Sie überwachen möchten, und ordnen Sie den Rückruf dem Dateideskriptor zu. Schließlich wird die Ereignisschleife dem Überwachungsobjekt zugeordnet und gleichzeitig die Schleife gestartet.

Das Folgende ist eine geringfügige Änderung der offiziellen Stichprobe.

#include <ev.h>
#include <iostream>

static void stdin_cb (EV_P_ ev_io *w, int revents)
{
    std::cout << "stdin ready\n";
    
    // I/Trennen Sie O von der Schleife.
    ev_io_stop (EV_A_ w);
    
    //Unterbrechen Sie die Ereignisschleife.
    ev_unloop (EV_A_ EVUNLOOP_ALL);
}

static void timeout_cb (EV_P_ ev_timer *w, int revents)
{
    std::cout << "timeout\n";

    //Stoppen Sie den Timer.
    ev_timer_stop (EV_A_ w);
    
    //Unterbrechen Sie die Ereignisschleife.
    ev_unloop (EV_A_ EVUNLOOP_ONE);
}

int main(int argc, const char * argv[])
{
    //Erstellen Sie eine Ereignisschleife.
    struct ev_loop *loop = ev_loop_new (0);

    // I/O Objekt beobachten.
    ev_io stdin_watcher;
    
    // I/Für O Objekte beobachten
    //Verknüpfen Sie Rückrufe mit FDs mit Ereignistypen.
    ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
    
    // I/Verknüpfen Sie eine Ereignisschleife mit einem O-Überwachungsobjekt.
    ev_io_start (loop, &stdin_watcher);


    //Erstellen Sie ein Timer-Objekt.
    ev_timer timeout_watcher;
    
    //Verknüpfen Sie einen Rückruf mit einem Zeitgeberobjekt und geben Sie eine Zeitüberschreitung an(Wiederholen Sie in 5 Sekunden 0).
    ev_timer_init (&timeout_watcher, timeout_cb, 5, 0.);
    
    //Verknüpfen Sie eine Ereignisschleife mit einem Timer-Objekt.
    ev_timer_start (loop, &timeout_watcher);
    
    //Schleifenstart.
    ev_loop (loop, 0);
    
    std::cout << "end¥n";
    
    //Verwerfen Sie die erstellte Ereignisschleife
    ev_loop_destroy(loop);
    
    return 0;
}

Da Sie mit xcode nicht mit der Befehlszeile interagieren können, versuchen Sie, mit gcc die folgende Methode zu erstellen.

# gcc -o test test.cpp -lev -I/usr/local/Cellar/libev/4.15/include/ -L/usr/local/Cellar/libev/4.15/lib/ -lstdc++

Erstellen einer Ereignisschleife

Das offizielle Beispiel verwendet ev_default_loop (), scheint jedoch nicht threadsicher zu sein. Im obigen Beispiel haben wir eine Ereignisschleife mit ev_loop_new (0) erstellt und mit ev_loop_destroy (Schleife) zerstört.

Das Argument gibt an, welcher asynchrone Prozess beim Erstellen dieser Ereignisschleife verwendet werden soll. Der Standardwert ist 0, der automatisch festgelegt wird.

Von libev verwendete asynchrone Technologie

Mit der folgenden Methode können Sie sehen, was im Backend verwendet wird.

unsigned int ev_supported_backends ()
  EVBACKEND_SELECT  = 0x00000001U, /* about anywhere */
  EVBACKEND_POLL    = 0x00000002U, /* !win */
  EVBACKEND_EPOLL   = 0x00000004U, /* linux */
  EVBACKEND_KQUEUE  = 0x00000008U, /* bsd */
  EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
  EVBACKEND_PORT    = 0x00000020U, /* solaris 10 */
  EVBACKEND_ALL     = 0x0000003FU, /* all known backends */
  EVBACKEND_MASK    = 0x0000FFFFU  /* all future backends */

Sie können die empfohlene asynchrone Verarbeitung mit der folgenden Methode erhalten.

unsigned int ev_recommended_backends();

Ereignisse, die überwacht werden können

Was gehandhabt werden kann, hängt von der Art des Überwachungsobjekts ab.

EV_READ EV_WRITE EV_TIMEOUT EV_PERIODIC EV_SIGNAL EV_CHILD EV_STAT EV_IDLE EV_PREPARE EV_CHECK EV_EMBED EV_FORK EV_ASYNC EV_ERROR

Beobachteter Objekttyp

ev_io ev_timer ev_periodic ev_signal ev_stat ev_idle ev_embed ev_fork ev_async

Nächstes Mal werde ich mich mit Steckdosen befassen.

Recommended Posts

Asynchrone Programmierung mit libev # 2
Asynchrone Programmierung mit libev
Asynchrone Programmierung mit libev # 3
3. 3. KI-Programmierung mit Python
Python-Programmierung mit Atom
Wettbewerbsfähige Programmierung mit Python
Shader-Programmierung mit pyOpenGL
Lineare Programmierung mit PuLP
Programmieren mit Python Flask
Versuchen Sie, mit einer Shell zu programmieren!
Versuchen Sie die GUI-Programmierung mit Hy
Programmier-Lernspiel mit SenseHAT
Netzwerkprogrammierung mit Python Scapy
[Python] Mit Pokemon erlernte objektorientierte Programmierung
Einfache Python + OpenCV-Programmierung mit Canopy
[Python] Asynchrone Anfrage mit async / await
Wettbewerbsprogrammierung mit Python Lokale Umgebungseinstellungen
GUI-Programmierung mit kivy ~ Teil 4 Verschiedene Tasten ~
Vollständiges Verständnis der asynchronen Python-Programmierung
Normal programmieren mit Node-RED-Programmierung mit Raspberry Pi 3
Führen Sie Embedded-Programmierung mit testgetriebener Entwicklung mit googletest durch
Soundprogrammierung mit Go (Super-Einführungslevel)
Was Sie mit Programmierkenntnissen machen können