IniReadSection mit mehreren AutoIT Instanzen auf die selbe Datei?

  • Hallo zusammen,

    ich hoffe ihr könnt mir ein weiteres Mal helfen, ich komme einfach nicht weiter, aber konnte mein Problem soweit eingrenzen.

    Das Ganze ist leider nicht so einfach erklärt und für Code Beispiele ist alles etwas zu umfangreich geworden, aber ich versuche mein bestes! :/

    Mein AutoIT Script ist mittlerweile recht umfangreich geworden und ich nutze jetzt schon seit sehr langen Forking mithilfe von AuThread (https://github.com/jesobreira/authread - mittlerweile aber fast komplett umgeschrieben und erweitert).

    Das nutze ich um zb. per Button parallel mehrere API/JSON Abfragen auszuführen und auszuwerten, ohne jeweils auf mein Hauptprogramm warten zu müssen.

    Funktioniert auch sehr schön und habe mittlerweile teilweise 5-8 parallele Instanzen am laufen.

    Leider zieht das ganz schön an der Performance und es kamen immer mehr und mehr hinzu.

    Mein AutoIT Script wird von einem Netzwerklaufwerk ausgeführt, was letztendlich dazu führt das jedes Mal, wenn parallele Abfragen gestartet werden, die Exe sich selbst von dem Netzwerklaufwerk mehrmals startet.

    Jetzt bin ich an einem Punkt angelangt wo es dadurch zu langsam läuft und wollte was dagegen tun.


    Ihr müsst wissen, die obigen Lösungen habe ich in einem größeren Zeitraum versucht und bin nie dahinter gekommen was egt genau falsch läuft.

    Mittlerweile habe ich ein besseres Logging für meine Anwendung... wo ich vorher nur die Consolen Ausgabe des MainThreads per Scite erhalten konnte, schreiben meine SubThreads ihre Logs in eine temporäre Log Datei.

    Darüber konnte ich weiter eingrenzen was egt beim Threadding passiert, oder eher nicht passiert.

    Die Kommunikation der einzelnen Threads geschieht wie im Original über "eine" Ini Datei.

    Funktioniert bisher super und gab keine Probleme, wenn "mehrere" Instanzen der gleichen Exe auf diese Zugreifen wollen.

    Wenn ich jetzt aber ein SubThread versucht auf diese Ini zuzugreifen, welche zb. meine *.a3x (oder wahrscheinlich auch aus Lösung 1 und 2 probierten >Exe'n), wird die Ini nie gelesen und nach 1-2 Sekunden beendet sich das Script von selbst (ohne Fehler, oder dergleichen).

    Hier ein Ausschnitt aus dem Teil, wo die Nachrichten gelesen werden - diese werden im SubThread in einer Endlosschleife ständig abgefragt bis eine Antwort kommt:

    "_ConsoleLog()" schreibt die typische Consolen Ausgabe und loggt diese in einer temporären Datei.

    Zum weiteren Eingrenzen hatte ich an mehreren Stellen die Ausgaben geloggt und zu prüfen an welche Stelle meine Subthreads kommen und an welche nicht.

    Die Zeile "Local $aArray = IniReadSection($__AuThread_sTmpFile, "msg")" erzeugt bei den SubThreads immer ein @ERROR Flag.

    Daraus schließe ich, dass die SubThreads keinen Zugriff auf die Ini Datei erhalten.

    Hier mein Log eines SubThreads:

    Wie ihr seht, startet die Endlosschleife immer wieder die "_AuThread_GetMessage()", welche versucht die Ini zu lesen, aber nicht schafft.

    Nochmal zur Verdeutlichung... wenn ich das Threadding mit mehreren Instanzen der "selben" Exe starte, können alle parallel auf diese Ini zugreifen.

    Im Regelfall wird die Schleife hier auch nur "einmal" aufgerufen zum Abfragen der Nachrichten.

    Ich hoffe ihr konntet mir soweit folgen. :saint:

    Meine eigentliche Frage... könnt ihr mir sagen was genau falsch läuft? :|

    Können die SubThreads, die quasi anderen Exen, oder eine *.a3x Datei ist nicht drauf zugreifen, weil die MainThread Exe diese blockiert?

    Wieso können dann SubThreads, die aus der gleichen Exe entstanden sind darauf zugreifen? :/

    Habt ihr eine Idee wie ich dieses Problem lösen, oder umgehen könnte?


    Vielen Dank schon mal fürs durchlesen und für die Hilfe. ;)

    Grüße

    borsTiHD

  • Ihr müsst wissen, die obigen Lösungen habe ich in einem größeren Zeitraum versucht und bin nie dahinter gekommen was egt genau falsch läuft.

    Wann genau beendet sich das Skript denn? Meine Vermutung wäre, dass du auf bestimmte Ressourcen zugreifst und das wegen dem veränderten WorkingDirectory (ist ja jetzt @TempDir) nicht funktioniert.

    Versuch mal die Dateien per FileRead zu lesen statt IniRead. Solange du permanent nichts in die Datei schreibst und so keine Inkonsistenzen entstehen, solltest du das Problem (der Zugriffsverweigerung) lösen können.

    Es kann sein, das IniRead die Datei sperrt.

  • Juhuu, erstmal vielen Dank für die schnelle Antwort. :)

    Zum Entwirren am Besten meine genutzte Verzeichnisstruktur:

    Code
    ;Das ist die Ini die von Main- und SubThread gelesen wird:
    Global Const $__AuThread_sTmpFile = @TempDir & "\" & @ScriptName & "_thread.tmp"
    
    Meine AutoIT Exe befindet sich in einem gewissen Unterordner, den ich hier einfach mal als "\" (Root) ansehe.
    
    \MyAutoIT.exe
    \Unterordner\SubThread.a3x


    Oh... als ich das geschrieben habe ist mir aufgefallen dasd meine SubThread.a3x wegen dem Zusatz @Scriptname versucht auf eine andere Datei zuzugreifen... :rofl:

    Fehler berichtigt... ich habe jetzt einen festen Namen vergeben und es löst mein Problem. :rolleyes:;(

    Ich muss das noch genauer testen, aber ich danke dir schon mal vielmals. :*

    Aber kannst du mir vlt noch eine Sache erklären?

    Das ist eine sehr kleiner Ausschnitt aus der Endlosschleife eines SubThreads:

    Kannst du mir erklären, wieso sich vorher die Threads von selbst beendeten in 1-2 Sekunden?

    Ohne vorhandene Fehlermeldungen?

    Sie haben jedenfalls immer wieder versucht eine nicht existierende Datei zu lesen.

  • Exits gibts.

    Die befinden sich allerdings nur "außerhalb" der oben genannten Schleife, oder in dem inneren der If-Abfrage, sobald eine Nachricht erkannt wurde, also "_AuThread_GetMessage() <> False" wird.

    Sollte das eintreten, sollten weitere Log Meldungen erscheinen, oder wegen einer unerwarteten Rückmeldung das Script abstürzen.

    Naja, ich belasse es mal dabei.

    Ich hätte eine weitere Frage.

    Ich vermute ich hab noch weitere Fehler drin, wo ich dich um Rat bitten würde.

    Das ganze scheint jetzt zu funktionieren, wenn ich aus dem Scite Editor herraus alles starte.

    Compiliert scheinen die Threads nicht korrekt zu starten.

    Obwohl ich eine PID erhalte, wird leider nichts in die Log Datei von den SubThreads geschrieben, weshalb ich davon ausgehe dass ich beim Run() was falsch mache.

  • Ist @WorkingDirectory was anderes als @WorkingDir?

    Ich habe nachträglich bei Run() zusätzlich als WorkingDir "@WorkingDir" als Parameter hinzugefügt (für BEIDE If-Zweige).

    Hat nichts geändert...

    Aber hier die Pfade:

    Code
    Not Compiled:
    _AuThread_StartThread() - Starte neuen SubThread: "D:\Stuff\Programmieren\AutoIT\AutoIt-v3.3.14.5\autoit3_x64.exe" /AutoIt3ExecuteScript "D:\AutoFan\AutoFan\AutoFan_v2_Threads.a3x" "--au-thread" "AufzurufendeThreadFunction"
    _AuThread_StartThread() - @WorkingDir: D:\AutoFan
    
    Compiled:
    _AuThread_StartThread() - Starte neuen SubThread: "D:\AutoFan\Compiled\AutoFan_v2.24_test.exe" /AutoIt3ExecuteScript "D:\AutoFan\Compiled\AutoFan\AutoFan_v2_Threads.a3x" "--au-thread" "AufzurufendeThreadFunction"
    _AuThread_StartThread() - @WorkingDir: D:\AutoFan\Compiled

    Achso, vergessen... ja, die "*.a3x" existiert in beiden Verzeichnissen.

  • Zur vollständigkeit hier noch die Pfade, wenn ich die Compilierte Exe benutze, aber mit dem alten "Run()" verfahren, sodass sich die Exe selbst für einen Thread startet:

    Code
    Compiled - mit eigener EXE:
    _AuThread_StartThread() - Starte neuen SubThread: D:\AutoFan\Compiled\AutoFan_v2.24_test.exe --au-thread "AufzurufendeThreadFunction"
    _AuThread_StartThread() - @WorkingDir: D:\AutoFan\Compiled

    Das beenden des Scripts kann ich derzeit nicht nachvollziehen.

    Wenn ich den SubThread starte, werden normalerweise direkt zu Beginn bereits Log Meldungen ausgegeben, bzw in eine Datei geschrieben, noch bevor der SubThread erkennt das es sich um einen SubThread etc. handelt.

    Mir kommt es eher so vor, als könnte die Compilierte Exe die *.a3x nicht starten.

    Run() gibt aber trotzdem eine PID zurück.

    Im Netz hatte ich als ich darüber gestolpert bin, gelesen man sollte auch im Hauptscript folgendes reinschreiben.

    Ist bei mir auch enthalten.

    Code
    #pragma("AutoItExecuteAllowed", True)

    Darum denke ich eher mein "Run()" ist falsch...



    -----------------

    €dit:

    Zum weiteren Eingrenzen habe ich in die erste Zeile der *.a3x Datei eine MsgBox eingefügt.

    Code
    MsgBox(4096, "", "SubThread is running")

    Starte ich aus Scite herraus mein Script und starte einen SubThread, wird die MsgBox angzeigt.

    Starte ich die compilierte Exe und dort einen SubThread, erscheint die MsgBox nicht.

    Desweiteren habe ich mich mit weiteren Consolen Ausgaben versichert, in welchen If-Zweig der MainThread springt, wenn er einen der oben genannten "Run()" Befehle ausführt.

    Die werden auch korrekt geroutet... es bleibt nachwievor bei diesem, der denke nicht klappt:

    Code
    $iPID = Run('"' & @ScriptFullPath & '" /AutoIt3ExecuteScript "' & $sAutoFanMultiThreadFile & '" "--au-thread" "' & $sCallback & '"', $sAutoFanRootPath)

    Weiterhin merkwürdig finde ich, dass ich eine PID zurückerhalte, aber nichtmal meine MsgBox aus der ersten Codezeile angezeigt wird.

    Zum weiteren Testen, prüfe ich auch nach dem Run() mit ProcessExists():

    Code
    If ProcessExists($iPID) Then
        _ConsoleLog("_AuThread_StartThread() - Process existiert - ProcessExists(): " & ProcessExists($iPID) & @CRLF)
    Else
        _ConsoleLog("_AuThread_StartThread() - Process existiert NICHT - ProcessExists(): " & ProcessExists($iPID) & @CRLF)
    EndIf

    Und auch hier wird mir bestätigt dass der SubThread erstellt wurd?!?!?!

    Einmal editiert, zuletzt von borsTiHD (17. September 2018 um 14:35)

  • Hm... Workaround für mich.

    Ich gehe nach oben genannter Lösung 1.

    Ich kopiere beim erstmaligen Start die Exe in einen Temp Ordner von Windows.

    Für die Threads starte ich dann die lokal existierende Exe aus dem Temp Ordner.

    Das geht jetzt, seitdem der Fehler mit "@Scriptname" behoben wurde.

    Ich denke mal das sollte auch wesentlich schneller sein, als die Exe jedesmal vom Netzwerklaufwerk zu starten.

    Somit hab ich mein erstes Problem dank dir trotzdem lösen können. :3

    Vielen Dank nochmals für alles.

    Ich finde es zwar immer noch Schade, dass ich die *.a3x Variante derzeit nicht nutzen kann, weil die wäre doch bestimmt nochmal schneller.

    Allerdings bekam ich hierbei auch den Gedanken das ja auch letzendlich die eigene Exe als Iinterpreter für die *.a3x Datei dient.

    Was wiederum bedeuten würde, auch hierbei würde ich die Exe vom Netzwerklaufwerk mehrmals starten... wäre dann wieder genauso langsam nehme ich an.