2 Programme steuern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
fsanders
User
Beiträge: 5
Registriert: Sonntag 17. Dezember 2023, 00:18

Ich frage um allgemeine Informationen zu folgenden Problem (damit ich weiß wo ich mich einlesen soll)

Ich möchte von meinem python-Programm aus 2 Konsolenprogramme starten. Die Programme senden wenn sie laufen Informationen, diese Informationen möchte ich lesen und falls notwendig auch wieder Informationen an die Programme senden.

Sind die beiden Programme Subprozesse? Threads? Brauche ich asyncio? Wie geht man das an?
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

die Frage ist ein bisschen allgemein bzw. es fehlen Details. Grundsätzlich kannst du jedes Python Skript beliebig oft starten, weil jedes in einem eigenen Prozess läuft. WENN du jedes Mal aus einem Terminal oder so startest.

Wenn du ein Python-Skript startest und dieses soll weitere Skripte starten, dann geht das auch. Du musst dann das weitere Skript importierbar machen (d.h. im Skript alles in importierbare Objekte (Funktion, Klassen) kapseln) und dann kannst du das via Threading oder Multiprocessing oder asyncio starten. Was die beste Wahl ist hängt davon ab, was gemacht werden soll.
Die Programmteile können dann über Queues oder Sockets miteinander kommunizieren. Tricky kann es werden, wenn du eine Dreieckskommunikation hast, d.h. jeder mit jedem direkt "sprechen" können muss. Also das geht auch, nur muss man da halt aufpassen, dass man keine Situation kreiiert, wo ein Deadlock entsteht.

Was hast du denn genau vor?

Gruß, noisefloor
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Programme sind Subprozesse. Wie man mit denen kommuniziert haengt signifikant von der Zielplatform ab. Windows, Mac oder Linux machen da grosse Unterschiede.
fsanders
User
Beiträge: 5
Registriert: Sonntag 17. Dezember 2023, 00:18

Ich möchte zwei Schachprogramme starten, und dann in beiden Richtungen kommunizieren. Ich bin schon etwas weiter gekommen, aber ich kann nicht gut senden und empfangen. z.B. schreiben die beiden stdout ineinander. muss ich das irgendwie buffern?
Und ich kann nicht immer senden.

Code: Alles auswählen

import asyncio
import subprocess

async def read_stdout(reader):
    while True:
        line = await reader.readline()
        if not line:
            break
        print(line.decode().strip())

async def send_input(writer, message_queue):
    while True:
        message = await message_queue.get()
        if message is None:
            break
        writer.write(message.encode())
        await writer.drain()

async def main():
    # Start the first console program
    process1 = await asyncio.create_subprocess_exec(
        "D:\\stockfish.exe",
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    )
    # Start the second console program
    process2 = await asyncio.create_subprocess_exec(
        "D:\\stockfishN.exe",
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    )

    message_queue1 = asyncio.Queue()
    message_queue2 = asyncio.Queue()

    # Read stdout of both programs continuously
    read_task1 = asyncio.create_task(read_stdout(process1.stdout))
    read_task2 = asyncio.create_task(read_stdout(process2.stdout))

    # Start tasks for sending input
    input_task1 = asyncio.create_task(send_input(process1.stdin, message_queue1))
    input_task2 = asyncio.create_task(send_input(process2.stdin, message_queue2))

    # Example interaction: sending input to process 1 and process 2
    await message_queue1.put("uci\n")
    await asyncio.sleep(1)
    await message_queue2.put("uci\n")
    # Example interaction: sending input to process 1 and process 2
    await message_queue1.put("go movetime 2000\n")
    await asyncio.sleep(1)
    await message_queue2.put("go movetime 2000\n")
    await message_queue1.put("go movetime 500\n")
    await asyncio.sleep(4)
    await message_queue2.put("quit\n")
    await message_queue1.put("quit\n")
    # Close the input queues
    await message_queue1.put(None)
    await message_queue2.put(None)




    # Wait for subprocesses to finish
    await asyncio.gather(read_task1, read_task2)
    await process1.wait()
    await process2.wait()

asyncio.run(main())
Antworten