Zwei Prozesse parallel ausführen



  • Hallo,

    folgende Problemstellung: Ich arbeite an einem Programm für die Feuerwehr, das bei Alarmeingang das Alarmfax auswertet, daraus eine Alarmdurchsage und Einsatzunterlagen erstellt.

    Das Programm besteht aus drei Komponenten (.exe-Dateien): Das Hauptprogramm, die Sprachausgabe und die Druckausgabe.

    Das Hauptprogramm verarbeitet das Fax und schreibt die Dateinamen (.wav-Dateien) der einzelnen Durchsageelemente in eine Datei. Gleiches geschieht mit den Dateinamen (.pdf-Dateien) für den Ausdruck der Einsatzunterlagen (Anfahrtskarten, Objektinfo, etc.)

    Nun rufe ich mit CreateProcess(..) die .exe-Dateien für den Ausdruck und die Alarmdurchsage auf. Diese lesen die Dateinamen ein und geben die Dateien über die entsprechenden Kanäle (Drucker, Soundkarte) aus.

    Problem ist nun, dass die Sprachausgabe nur über PlaySound() mit SND_SYNC als Parameter funktioniert. Dies hängt damit zusammen, dass die Durchsage mehrmals wiederholt wird, jeweils mit einigen Sekunden Pause zwischen zwei Durchsagen. Diese Pause steuere ich über einen Timer und irgendwie gibt es Konflikte zwischen dem Timer und dem Objekt TMediaplayer, weswegen ich auf PlaySound() ausgewichen bin. Letztere wiederum hält den Prozessor bis zum Ende der Audiodatei fest. (Siehe Charles Petzold "Windows Programmierung", Kap.3 "Das Abspielen einer Audiodatei") Damit wird allerdings auch der zweite Prozess zum Ausdrucken blockiert, was nicht ganz im Sinne des Erfinders ist, da Sprachausgabe und Druckausgabe möglichst parallel ablaufen sollen.

    Hat da irgendjemand ne Lösung ?
    Multithread ? Hab' ich wenig Erfahrung mit. Kann ich irgendwie sicherstellen dass mit CreateProcess() (oder evtl. ShellExecute) ein bestimmter Prozessorkern angesprochen wird, und ist das eine Lösung ?
    DirectSound besser als PlaySound()? Bin beim googlen darüber gestolpert, dass das nicht mehr zeitgemäß sei.

    Danke schon mal für die Hilfe.

    Beste Grüße
    Andreas



  • Hallo,

    Multithread ist eigentlich nicht so schwer. Schau dir doch erstmal die Doku zu TThread an.
    Alternativ kannst du auch ShellExecuteEx nehmen. Das hat mehr Optionen und liefert dir auch einen Processhandle. Den wiederum kannst du in SetProcessAffinityMask verwenden um die Prozessoraffinität zu steuern. Das ist aber alles eher eine Frage für WinAPI.



  • Deine zwei .exen laufen doch in verschiedenen Prozessen!? Wenn der eine Prozess auf PlaySound() wartet, läuft der andere doch weiter!?



  • Hallo dot,

    dachte ich eigentlich auch, aber anscheinend laufen beide Prozesse auf dem gleichen Kern, der ja von PlaySound() blockiert wird.

    Ich ging davon aus, dass, wenn ich mit CreateProcess() zwei unterschiedliche .exe aufrufe, beide unabhängig voneinander laufen. Tun sie aber vermutlich nicht.

    Zumindest zeigt sich das darin, dass der Druckauftrag erst in der Pause zwischen zwei Ansagen wirklich zum Laufen kommt



  • Das kann ich mir nicht vorstellen, ich bin mir sicher, dass das Problem wo anders liegt. Wie und wo und wann werden die beiden Prozesse denn genau gestartet?



  • Also zuerst wird das Fax als .SFF oder .TIF-Datei geladen, dann läuft eine Texterkennungsroutine drüber und die wichtigen Informationen gehen in eine Datenstruktur (Ops_Data). Mit Hilfe dieser werden die .wav bzw. .pdf - Dateien zusammengestellt. Dazu habe ich zwei Funktionen, PrintAlarm und VoiceAlarm die nacheinander aufgerufen werden.

    // start Printer operations
    PrintAlarm(Ops_Data,edition);
    // clear OCR_Memo and hide OCR_Form to be ready for next alarm
    OCR_Memo->Clear();
    OCR_Form->Close();
    // start Voice operations
    if (FaxSetup->VoiceActive->Checked) VoiceAlarm(Ops_Data);

    beide Funktionen stellen zuerst die einzelnen Dateien zusammen und rufen dann mit praktisch identischen CreateProcess's die jeweilige EXE-Datei auf.

    // .. and finally start PrintModule
    String filename = AppPath + "FwFaxPrint.exe";
    String cmdline = filename + " -index=" + IntToStr(edition);
    STARTUPINFO psi;
    PROCESS_INFORMATION ppi;
    ZeroMemory(&psi,sizeof(psi));
    psi.cb = sizeof(psi);
    psi.dwFlags = STARTF_USESHOWWINDOW;
    psi.wShowWindow = SW_SHOW;
    ZeroMemory(&ppi,sizeof(ppi));
    char * szFN = new char[filename.Length()+1];
    StrPCopy(szFN,filename);
    char * szCL = new char[cmdline.Length()+1];
    StrPCopy(szCL,cmdline);
    if ( CreateProcess( szFN, szCL,NULL, NULL,false,CREATE_NEW_CONSOLE, NULL, NULL, &psi, &ppi ) ) {



  • Und du hast da nicht irgendwo ein WaitForSingleObject() drin oder so?



  • Nein hab ich nicht. Die Funktionen laufen auch ohne WaitForSingleObject(). Inwiefern würde mir das weiterhelfen ? Ah, verstehe, Du meinst das WaitForSingleObject würde die weitere Ausführung des zweiten Prozesses evtl. blockieren, oder ?


Anmelden zum Antworten