Anzeige:
Ergebnis 1 bis 4 von 4

Thema: [C++] Interprozess-Kommunikation mit FIFOs und Qt 3

  1. #1
    Registrierter Benutzer
    Registriert seit
    19.07.2004
    Beiträge
    50

    [C++] Interprozess-Kommunikation mit FIFOs und Qt 3

    Wenn ihr von außen (also mit irgendwelchen anderen Programmen) auf ein bereits laufendes Programm zugreifen wollt, bietet es sich an, dies unter Linux über "Named Pipes" zu machen (siehe dazu "man fifo" oder den entsprechenden Eintrag in der Wikipedia).

    Hier soll nun erläutert werden, wie ihr in euer Programm mit QT 3 (Produkt von Trolltech) einen Thread einbaut, der Eingaben von einer bestimmten Pipe empfängt (die Bearbeitung der Eingaben bleibt euch selbst überlassen ). Einige Kenntnisse in C++ und QT werden vorausgesetzt.

    Wir brauchen zunächst einen Namen für das Programm, wir nennen es ThreadApp (). Anschließend legen wir einen Ordner "/var/run/threadapp/" an und erstellen in diesem Ordner eine Pipe:
    Code:
    mkdir /var/run/threadapp
    cd /var/run/threadapp
    mkfifo input.fifo
    Wir erstellen jetzt die Quellcode-Dateien für unser Projekt. Erstellt mit $EDITOR die beiden folgenden Dateien:

    ThreadApp.h
    Code:
    #include <iostream>
    #include <string>
    
    #include <qfile.h>
    #include <qtextstream.h>
    #include <qstring.h>
    
    #include <qthread.h>
    
    class ThreadApp : public QThread
    {
    public:
      ThreadApp();
      
      void run();
      void stop();
        
    private:  
      bool stopped;
    };
    ThreadApp.cpp
    Code:
    #include "ThreadApp.h"
    
    ThreadApp::ThreadApp()
    {
      this->stopped = false;
    }
    
    
    void ThreadApp::run()
    {
      QFile file("/var/run/threadapp/input.fifo");
      
      if (!file.open(IO_ReadOnly | IO_Translate)) return;
      
      while (!this->stopped)
      {
        QTextStream stream(&file);
      
        QString s;
      
        while ((s = stream.readLine()) != NULL)
        {
          // Mit dem String könnt ihr jetzt tun, was immer ihr wollt,
          // mit std::string(s) könnt ihr ihn auch in einen STL-String
          // umwandeln
          // Denkt bei der Ausgabe an das "std::endl", da ansonsten der
          // Buffer nicht geleert wird und nichts ausgegeben wird.
          // Achtung: "\n" != std::endl
          std::cout << s << std::endl;
        }
      }
    }
    
    
    void ThreadApp::stop()
    {
      this->stopped = true;
    }
    
    
    int main()
    {
      ThreadApp t;
      
      t.start(QThread::HighestPriority);
      
      // Verhindert, dass das Programm zu früh beendet wird
      while (t.running())
      {
      }
      
      return 0;
    }
    Das Projekt wird kompiliert, indem zunächst mit "qmake" ein Makefile erzeugt und anschließend mit "make" das Programm erzeugt wird, vorher müssen wir noch eine Projektdatei erstellen und diese ein wenig modifizieren (es wird davon ausgegangen, dass die Quellcode-Dateien in dem Ordner "ThreadApp" sind, ansonsten heißt die Projektdatei anders, *.pro müsste es genauso tun):
    Code:
    qmake -project
    echo "CONFIG += thread" >> ThreadApp.pro
    qmake
    make
    Nun könnt ihr euer Programm testen:
    Code:
    ./ThreadApp &
    echo "Test" > /var/run/threadapp/input.fifo
    Viel Spaß noch. Wenn ihr Fehler findet, postet einfach mal, mal schaun was sich machen lässt...

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Man müsste das jetzt austesten, aber vermutlich kann man das in Programmen mit Eventloop auch ohne Thread machen, wenn man den Filedescriptor des FIFOs mit einem QSocketNotifier überwacht.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    19.07.2004
    Beiträge
    50
    Das ganze Programm geht natürlich auch ganz ohne Threads, das ist klar, wenn man z.B. die äußere Schleife in ThreadApp::run() nach Main() packt, aber es kann ja sein, dass das Programm zusätzlich noch was anderes machen soll, außer nur Befehle aus der Pipe auslesen.

    Die Methode mit QSocketNotifier kenn ich noch nicht, werd mich direkt mal schlau machen...

    Ein Nachteil von QSocketNotifier ist auf jeden Fall, dass er nur mit GUI-Threads verwendet werden kann, das könnte dann wahrscheinlich Probleme geben, wenn kein X läuft.
    Geändert von KL47 (29-01-2005 um 15:37 Uhr)

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von KL47
    Das ganze Programm geht natürlich auch ganz ohne Threads, das ist klar, wenn man z.B. die äußere Schleife in ThreadApp::run() nach Main() packt, aber es kann ja sein, dass das Programm zusätzlich noch was anderes machen soll, außer nur Befehle aus der Pipe auslesen.
    Schon klar, darum hab ich ja geschrieben "in Programmen mit Eventloop"

    Die Methode mit QSocketNotifier kenn ich noch nicht, werd mich direkt mal schlau machen...
    Falls es funktioniert wäre es cool, wenn du diese Variante auch posten könntest.

    Ein Nachteil von QSocketNotifier ist auf jeden Fall, dass er nur mit GUI-Threads verwendet werden kann, das könnte dann wahrscheinlich Probleme geben, wenn kein X läuft.
    Die Qt Eventloop ist nicht von GUI oder X abhängig. Man braucht nur eine QApplication Instanz und Loop mit QApplication::exec() zu starten.

    Da das in einer Qt Applikation einfach sehr wahrscheinlich der Fall ist, wäre ein Lösung, die ohne Threads auskommt, noch schöner, denn Threads haben bekanntlich nicht nur Vorteile

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •