Kommunikation zwischen zwei Python Programmen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo zusammen,
    Ich arbeite dereit an einem Projekt und bin auf folgendes Problem gestoßen. Und zwar wie im Titel beschrieben geht es um die Kommunikation zweier Python Programm.

    Programmaufbau:
    Ich sende über Telegram einen Nachricht.
    Durch diese Nachricht wird ein Python Skript ausgeführt und dannach wieder geschlossen. (Das funktioniert)
    Parallel dazu läuft ein anderes Python Skript.
    Das Skript das durch die Nachricht empfangen hat muss dem Skript das parallel läuft "bescheid sagen" welche Nachricht gesendet wurde.
       
    Wie kriege ich die Kommunikation zwischen den zwei Skripten hin? Oder kann ich das evtl schlauer lösen?
    Mein Prof meinte er hätte das bis jetzt immer über die "Erstellung von Dateien" gesehen, dass das eine Programm diese erstellt und das andere diese liest aber da bräuchte ich auch hilfe, wie ich dies mache!

    Freue mich auf die Antworten!

    Grüße Benedikt

  • Hallo Benedikt,

    das Stichwort heißt "named pipes". Dadurch wird eine Inter-Prozess-Kommunikation (IPC) auf FIFO-Basis zwischen zwei Programmen ermöglicht. Das eine Programm (Sender) schreibt in eine Datei. Das andere Programm (Empfänger) liest die Daten aus - wobei das Auslesen wörtlich zu nehmen ist: Die Datei ist danach leer.

    Wie das in der Programmiersprache Icon funktioniert, habe ich mal in einem Thread vorgestellt. Da es sich dabei um reine Datei-I/O handelt, lässt sich dies in jede beliebige Programmiersprache übertragen.

    Da kommst Du ohne Sockets aus - und vermeidest auf diese Weise jegliche Netzwerkprobleme. (Obwohl ich sonst auch ein großer Fan von Sockets bin!)

    Der Vorteil von named pipes besteht darin, dass der Sender anhand der leeren Datei immer erkennen kann, dass der Empfänger die Daten erhalten hat. Eine implizite Rückmeldung ist somit nicht erforderlich - wobei sich dann auch die Frage stellen würde, wie dies aussehen könnte...


    Was über named pipes noch funktioniert, ist die Übergabe von Variablennamen und deren Inhalte von einer Anwendung zur anderen (s. Beitrag #2 im o.a. Link).


    Eine andere Möglichkeit der Kommunikation zwischen zwei Anwendungen besteht darin, die betreffenden Anwendungen über eine gemeinsame Basis zu starten und dann über Umgebungsvariablen zu kommunizieren. Diese können sowohl über Befehle der Programmiersprache als auch über Linux-Kommandos gesetzt werden.


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    3 Mal editiert, zuletzt von Andreas (17. Oktober 2017 um 21:30)

  • Eine andere Möglichkeit wäre auch mithilfe eines Queue-Servers der im Hintergrund permanent läuft und die Scripts darauf dann zugreifen:

    Code
    sudo apt-get install beanstalkd
    sudo pip3 install pystalkd

    Der Dienst beanstalkd läuft wie gesagt permanent im Hintergrund und die Scripts können sich jederzeit dort hin verbinden. Auch mehrere verschiedene Queue's können angelegt werden sowie 'Queue Priority Level's festgelegt werden etc.. Wie das Queue heißt legt man selber fest.
    Die Queue Einträge bleiben dabei solange erhalten bis man ihn explizit löscht. Auch kann man sich übers Netzwerk auf diesen Queue-Server verbinden...

    Beispiel:

    Main.py
    [code=php]
    import time
    import shlex
    from pystalkd import Beanstalkd

    queue = Beanstalkd.Connection(host="127.0.0.1", port=11300)
    queue.use("ControlCommand")

    def queuePurge(queue, queueName):
    queue.watch(queueName)
    jobsDeleted = 0
    jobsReady = 1
    while jobsReady != 0:
    try:
    jobsReady = queue.stats_tube(queueName)['current-jobs-ready']
    except:
    jobsReady = 0
    if jobsReady != 0:
    job = queue.reserve()
    job.delete()
    jobsDeleted += 1
    return jobsDeleted

    # purge anything in the queues left from last execution
    if queue.stats_tube('ControlCommand')['current-jobs-ready'] > 0:
    print("Queue: Control Command purged of %s entries." % queuePurge(queue, "ControlCommand"))

    processing = True
    while processing:
    queue.watch('ControlCommand')
    try:
    jobsReady = queue.stats_tube('ControlCommand')['current-jobs-ready']
    except:
    jobsReady = 0
    if jobsReady != 0:
    print("Processing 'ControlCommand'")
    job = queue.reserve()
    commandLine = job.body
    job.delete()
    commandParser = shlex.shlex(commandLine, posix=True)
    commandParser.whitespace += ':'
    commandParser.whitespace_split = True
    commandParsed = list(commandParser)
    command = commandParsed[0]
    print("Received Command: %s:%s" % (command, commandParsed[1]))

    # Act on the command passed as the first argument
    if command == "Terminate":
    processing = False
    elif command == "newMessage":
    print("...received new Message: %s" % commandParsed[1])

    time.sleep(.5)
    [/php]

    Client.py
    [code=php]
    from pystalkd import Beanstalkd

    queue = Beanstalkd.Connection(host="127.0.0.1", port=11300)
    queue.use("ControlCommand")


    queue.put("newMessage:bla")
    [/php]


    [...] Da kommst Du ohne Sockets aus - und vermeidest auf diese Weise jegliche Netzwerkprobleme.

    *hust* Probleme mit 127.0.0.1? Wie schaffst du das? ;)


    Wie kriege ich die Kommunikation zwischen den zwei Skripten hin? Oder kann ich das evtl schlauer lösen?
    Mein Prof meinte er hätte das bis jetzt immer über die "Erstellung von Dateien" gesehen, dass das eine Programm diese erstellt und das andere diese liest aber da bräuchte ich auch hilfe, wie ich dies mache!

    Man sollte so gut es geht unnötige Schreibzugriffe auf dem Datenträger vermeiden. Dh wenn dann nur über Dateien die in zB tmpfs liegen, aber solch ein Lösungsweg ist ziemlich unschön.

    Bei meinem ersten Ansatz bzgl. RoPi nutzte ich ebenfalls Sockets zwischen allen Programmen, mittlerweile nutze ich aber besagten Queue Server denn so gehen keine gesendeten Daten verloren ;)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!