Autor Beitrag
TomyN
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32
Erhaltene Danke: 2

Win10
D5 Std., Turbo-Delphi (w32), Delphi 2010
BeitragVerfasst: Mo 28.04.14 22:26 
Hallo,

ich habe in meiner Anwendung einen Thread, der so aussieht:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
implementation
  uses ocpData, windows, uAsioVars, AudioTools;

{ TAsioOutThread }

procedure TAsioOutThread.Execute;
var eh: Array [0..1of THandle;
begin
  { Thread-Code hier einfügen }
  eh[0]:= outEvent;
  eh[1]:= closeEvent;
  repeat
    if waitForMultipleObjects(2, @eh[0], FALSE, 500) = wait_object_0 then begin
      if (driverState = 4then begin
         enterCriticalSection(outSync);
        try
          if assigned(dpOut) then
            outCallBackEx(dpOut, puffersize, outMode);
            //ocp(dpOut, puffersize, outMode); //Hier haben wir Zeit... denk ich..
        finally
          leaveCriticalSection(outSync);
        end;
      end;
    end;
  until terminated;
end;

end.


Im 'Normalbetrieb' wird der Thread regelmässig mit dem outEvent versorgt und führt dann die Routine OutcallBackEX aus. Das funktioniert unter winXP und win7 (Vista nicht getestet) wunderbar, unter win8.1 wird der Thread genau einmal ausgeführt. Wenn ich die Routine auskommentiere, dann kommt der Event regelmässig an.
Parallel läuft ein zweiter Thread für den Input, auch Event gesteuert, der funktioniert ohne Probleme, allerdings ohne den Aufruf eine Procedur, sondern nur mit Mathe und Api-Funktionen, aber auch mit Globalen Variablen.
Hat irgendwer eine Idee oder einen Tip, wo ich suchen kann?

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19284
Erhaltene Danke: 1742

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 28.04.14 22:36 
user profile iconTomyN hat folgendes geschrieben Zum zitierten Posting springen:
unter win8.1 wird der Thread genau einmal ausgeführt
Was heißt denn das? Bleibt der Thread dann hängen? Oder wird er beendet?

Wenn er hängen bleibt, sollten die Stacktraces der Threads Aufschluss geben was passiert. Dann sähe das sehr nach einem Deadlock aus, sprich zwei Threads warten gegenseitig auf eine Form der Synchronisierung (Synchronize, Critical Section, Event, ...).
Wenn Delphi auf dem entsprechenden PC läuft, brauchst du nur, sobald es hängt, auf Pause zu gehen und in der Threadliste alle Threads durchgehen und ihre Stacktraces anschauen.
TomyN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32
Erhaltene Danke: 2

Win10
D5 Std., Turbo-Delphi (w32), Delphi 2010
BeitragVerfasst: Mo 28.04.14 22:45 
Hi,

leider läuft Delphi nicht auf dem Rechner.

Ich habe schon die folgenden Tests gemacht:

- Eintrag ins Logfile nach dem EnterCriticalSection
- Eintrag ins Logfile nach dem LeaveCriticalSection
- Eintrag nach dem Until

Fazit:
Es kommt genau einmal Enter + Leave, Terminate (nach Until) genau dann wann es soll (wenn der Thread beendet wird). Lasse ich die Procedure raus (habe also nur noch Enter + Leave), dann kommen die Einträge regelmässig.
Der einmalige durchlauf kommt genau einmal nach dem Erzeugen + Start des Threads (der Thread wird Resumed erzeugt, und dann einmalig mit Start gestartet)

Tomy
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19284
Erhaltene Danke: 1742

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 29.04.14 10:32 
Das kann ja nur heißen, dass deine beiden if-Bedingungen nicht beide erfüllt sind und das Programm daher dort nicht ankommt.

Am besten loggst du einmal an dem Punkt, an dem DriverState und deine Events gesetzt werden und das Ergebnis der if-Abfragen im Thread. So solltest du ja herausbekommen ob das Setzen oder das Empfangen im Thread schief geht.

Rein ins Blaue geraten würde ich vermuten, dass das Setzen nicht oder nicht korrekt passiert.
TomyN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32
Erhaltene Danke: 2

Win10
D5 Std., Turbo-Delphi (w32), Delphi 2010
BeitragVerfasst: Di 29.04.14 20:17 
So,

nun hab ich das Problem gefunden. Es lag natürlich wieder woanders, und zwar im outCallbackEX.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
var pi: pLongInt;
    pd: double;
    Faktor: double;
    i: integer;


....
   out_32: begin
             faktor:= $7FFFFFFF * siglatch.Laut;
             pi:= speicher;
             for i:=1 to Zahl do begin
               pi^:= round(faktor * pd^);
               inc(pD);
               inc(pi);
             end;
           end;
....


blieb unter win8.1 beim ersten Schleifendurchlauf bei pi^:= round(Faktor * pd^) kommentarlos hängen.

Die Lösung ist:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
   out_32: begin
             faktor:= $7FFFFFFF * siglatch.Laut;
             pi:= speicher;
             for i:=1 to Zahl do begin
             pi^:= longInt(round(faktor * pd^));
             inc(pD);
             inc(pi);
           end;
         end;


Nach viel Grübeln kann man das sicherlich irgendwie erklären, aber weder die Typprüfung im Compiler noch Eurekalog haben das irgendwie angemault.. .:-(

Vielen Dank für die Unterstützung

Tomy

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt