Thread warten lassen [Erledigt]

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Thread warten lassen [Erledigt]

Beitrag von Jan »

Ich habe folgendes Problem:

Funktion A wird in Thread A aufgerufen
Irgendwann kommt eine FOR...NEXT-Schleife
In dieser Schleife wird x-mal eine Funktion B in Thread B aufgerufen
Nach Abschluß von Funktion B wird Thread B beendet, und es wird auf Thread A zurückgesprungen

Jetzt habe ich aber folgendes Problem: Thread A muß warten, bis Thread B beendet ist. Thread B darf innerhalb der FOR...NEXT-Schleife nicht mehrfach parallel aufgerufen werden, sondern schön sauber nacheinander. Also etwas in der Richtung

Code: Alles auswählen

For i := 1 TO nWasImmer
    Lass Thread A warten
    Rufe Funktion B auf
    Warte auf die Beendigung von Thread B
    Lasse Thread A weiterlaufen
Next
Ich habe mir ThreadWait(), :synchronize(), Signal() angesehen. Aber irgendwie sehe ich den Wald vor lauter Bäumen nicht.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Hallo Jan,

sieh dir unter den Beispielen im Zweig Thread, das mit der Kaffeemaschiene an, dieses trifft dein Problem genau.

PS: wobei ich in diesem Beispiel nicht erkennen kann, warum du überhaupt 2 Threads aufrufst.
Wenn einer grundsätzlich auf den anderen warten muss, währe es einfacher das ohne Thread zu machen.
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Hallo Hubert,

prinzipiell hast Du natürlich Recht. Funktion B ist aber eigentlich unabhängig aufrufbar, und soll da in einem eigenen Thread laufen. Ich habe jetzt aber eine neue Übersichtsfunktion erstellt, die aus verschiedenen vorhandenen Funktionen ein Gesamtwerk zusammenstellt. Und da ist der Thread ein wenig im Weg.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Ich bekomms nicht hin. Kann mir jemand eventuell mit ein paar Zeilen Mustercode aushelfen? Wo muß das Signal():new() hin, wo das oSignal:wait(), wo das oSignal:signal()? Bin offensichtlich zu blöd dafür.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Hallo Jan,

ich schreibe öffters Funktionen, die sowohl im normalen als auch im eigenen Thread ablaufen.
So ist es auch bei der Entwicklung einfacher.

Im Fenster wird z.B. bei einem Pushbutton folgender Code aufgerufen um den separaten Thread zu starten.
Hier wird der separate Thread hauptsächlich benutzt, damit die GUI weiterhin funktioniert.

Code: Alles auswählen

method DateiImport()    
     ::oThread := Thread():new()
     ::oThread:start("DoDateiImport", SELF , cDatei )
die aufgerufene Funktion kümmert sich um alles selbst und erhält als Parameter das Fenster (SELF), so kann ich z.B. Verlaufsanzeigen steuern (ich nutze XbpSLE mit Anzahl der Datensätze)
Diese kann mit oder ohne Thread genau gleich gestartet werden !

Code: Alles auswählen

*---------------------------------------------------------------------------------------
function DoDateiImport(oXbp, cDatei)
   local altselect := select()

   if file(cDatei)                          // sicher ist sicher, das ist die einzulesende Textdatei
      ... Vorbelegungen
      begin sequence                  // somit kann ich BREAK für Abbruch nutzen

      USE MeineDatendatei NEW   // wichtig, im neuen Selektbereich öffnen und
      set index to ...
      nH := Select()                   // den Selektbereich in Variable speichern (numerisch !)
      ...
      do while .t.
          sleep(0)                       // gibt Rechenzeit an andere ab, sonst wir ein CPU Kern komplett ausgelastet.
          if oXbp:Abbruch 
             ...  
             BREAK
          endif
          ... Aktionen, was auch immer 
          oXbp:sleSatzAnzahl:SetData(alltrim(str(nAnz))) // hier zähle ich die laufende Anzahl hoch, OHNE THREAD hinkt die Anzeige im SLE hinterher.
          ...
      enddo
      beep()                             // es kann länger dauern ;-) 
      end sequence

   endif

   if (nH)->(used())
      (nH)->(dbskip(0))                   // sicher ist sicher
      (nH)->(dbcloseArea())               // sicher ist sicher
   endif

   select(altselect)

return nFehler
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Tom »

Einfach nach dem Start des Threads ein Synchronize(0), feddisch. Dann wartet der aufrufende Thread auf die Beendigung des aufgerufenen Threads.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von UliTs »

Jan hat geschrieben:

Code: Alles auswählen

For i := 1 TO nWasImmer
    Lass Thread A warten
    Rufe Funktion B auf
    Warte auf die Beendigung von Thread B
    Lasse Thread A weiterlaufen
Next
Hallo Jan, bevor ich mit was falschem loslege :-) : läuft der obige Code in einem dritten Thread?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Tom: Synchrionize() ist doch eine Methode von Thread(). Das heißt, ich muß den Thread A als Variable an Thread B übergeben, und in Thread B dann ein oThread_A:synchronize(0) ausführen?

Uli: Nein, das geht nicht. Ich muß Thread B mehrfach aufrufen in der Schleife. Egal wie, ich muß den aufrufenden Thread immer stoppen, bis Thread B abgearbeitet ist. Eine Verlagerung in einen dritten Thread würde da nichts bringen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Hi,

schau dir doch das Beispiel an:

K:\XPPW32\source\samples\basics\THREAD\Coffee.prg

10 Programmierer wollen gleichzeitig Kaffee, aber nur einer zu einer Zeit darf, das wird über eine SYNC METHOD geregelt.
Diese Definition stellt schon sicher, dass mehrere Aufrufe von dieser Methode nacheinander ausgeführt werden.

Du brauchst das wohl eher nicht, für dich gilt die andere Anforderung, wobei mehrere passen würden:
1) Wenn die Kaffeemaschine leer ist, muß Thread (K) angehalten werden, bis ein Programmierer (P) die Kaffeemaschine füllt.
Bei dir wäre das, Thread A muss warten bis B ferstig ist ... oder verstehe ich das falsch, dass das Hauptprogramm warten muss, bis der Thread fertig ist ... ?

Hast du im Hauptprogramm (FOR NEXT) zwei Threadobjekte, die du steuern willst, oder startest du in
der For Next Schleife jeweils einzelne Threads und willst warten bis der einzelne durchgelaufen ist ?

Im letzteren Fall könntest du jeweils warten bis oThread:active() auf .f. geht:

Code: Alles auswählen

for x := 1 to 10 
    oThreadA:start(...)
    do while oThreadA:active()
        sleep(0)
    enddo
    oThreadB:start(...)
    do while oThreadB:active()
        sleep(0)
    enddo
next
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Hubert,

das Kaffeee-Beispiel hatte ich mir ja angesehen. Und nicht wirklich verstanden.

zu Deiner Frage. Thread A in Funktion A ruft eine Funktion B auf, in der der Thread B gestartet wird. Und ja, Thread A muß warten, bis Thread B (und damit Funktion B) beendet ist.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von andreas »

Hallo Jan,

soweit ich weiss, gibt es in Xbase eine Signal-Klasse, die genau dass macht, was du möchtest. Ich habe es zwar selber noch nicht ausprobiert, weil ich es nicht gebraucht habe, aber ich glaube, dass in der Hilfe das ganze sehr gut beschreiben war.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Tja, hab ich auch ausprobiert. Ohne Erfolg.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von andreas »

ich werde es mir ansehen, wenn ich wieder zu hause bin.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Hallo Jan,

du hast mich nicht verstanden, läuft die FOR NEXT Schleife in Thread A ab oder im Hauptprogramm ?
Thread A ist ja nicht das Hauptprogramm oder ?

Wir brauchen genauere Infos über deinen Aufbau, also bitte dein Beispiel um die Threadobjektvariablen ergänzen,
wo werden diese erzeugt und wo gestartet. Laufen beide endlos etc. ?

Grundsätzlich kann man sagen, dass das Signal-Objekt beiden Threads bekannt sein muss.
Das geht nur wenn es im Hauptprogramm angelegt wurde.
Den Threads übergibt man diese als Parameter.
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Hubert,

genau so, wie ich es beschrieben habe.

Funktion A wird aufgerufen, diese startet Thread A. Innerhalb Thread A wird in der Schleife Funktion B aufgerufen, der Thread B startet. Mit Beendigung von Funktion B wird auch Thread B beendet.

Der Einfachheit halber heißen alle Threadvariablen oThread. Sind alle LOCALs in den jeweiligen Funktionen.

Fehlt noch was?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Hallo Jan,

als visueller Mensch sehe ich lieber den gut formatierten Quellcode als mir über sprachliche Ausformulierung Gedanken zu machen,
aber wenn ich dich recht verstanden habe, hat TOM dir die richtige Lösung genannt.
Als Quellcode hättest du es vielleicht dann auch verstanden ;-)

Eine deiner Ausführungen ist z.B. dass das Ende von Funktion B den Thread B beendet.
Wenn das so ist, dann hättest du kein Problem, denn der Aufruf von Funktion B wird die Schleife solange blockieren, bis diese Funktion beendet wird.
Ich vermute eher, dass Funktion B zwar einen Thread B startet, aber nicht auf dessen Ende wartet.

In der Hilfe steht hierzu:

Code: Alles auswählen

Hinweis: Wenn der aktuelle ThreadA auf die Beendigung eines zweiten Threads warten muß, gibt es zwei Möglichkeiten: 
    DO WHILE .NOT. oThreadB:synchronize(1) 
       <Programm Code> 
    ENDDO 
 
/* oder */ 

    oThreadB:synchronize(0) 
Gruß
Hubert
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von UliTs »

Jan hat geschrieben:Uli: Nein, das geht nicht. Ich muß Thread B mehrfach aufrufen in der Schleife. Egal wie, ich muß den aufrufenden Thread immer stoppen, bis Thread B abgearbeitet ist. Eine Verlagerung in einen dritten Thread würde da nichts bringen.
Jan
Hallo Jan,
ich glaube, Hubert hat das gleiche Problem wie ich!
In welchem Thread läuft die Schleife denn jetzt ab? Ich vermute mal, in Thread A
Dann könnte es wie folgt aussehen:

Code: Alles auswählen

For i := 1 TO nWasImmer
    oSignalThreadB:Signal()  // Auslösung von ThreadB, damit im ThreadB Funktion B ausgeführt wird
    oSignalThreadA:wait( 0 ) // unendlich "schlafen", bis oSignalThreadA ausgelöst wird
    Lasse Thread A weiterlaufen
Next i
In ThreadB sieht es wie folgt aus:

Code: Alles auswählen

DO WHILE TRUE
  oSignalThreadB:wait(0)   // unendlich "schlafen", bis oSignalThreadB ausgelöst wird
  rufe Funktion B auf
  osignalThreadA:Signal()  // teile ThreadA mit, dass Funktion B aufgerufen wurde
ENDDO
Auf oSignalThreadA und oSignalThreadB mußt Du in beiden Threads zugreifen können.
Ach ja, und oSignalThreadA+B müssen natürlich vorher initialisiert werden:

Code: Alles auswählen

oSignalThreadA := Signal():new()
oSignalThreadB := Signal():new()
Uli

P.S. Kannst Du nicht einfach aus Funktion B eine SYNC-Methode machen?
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

OK, also noch einmal von vorne. Noch einmal.

Es gibt eine Funktion A. Diese startet Thread A. In Thead A gibt es eine Schleife, die ruft Funktion B auf, diese Thread B. Sobald Funktion B und damit Thread B beendet sind, geht es wieder zurück in Thread A und die Schleife. Funktion B und damit Thread B werden so oft aufgerufen und beendet, wie die Schleife das vorgibt.

Fehlt noch was?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von UliTs »

Jan hat geschrieben:Hubert,

genau so, wie ich es beschrieben habe.

Funktion A wird aufgerufen, diese startet Thread A. Innerhalb Thread A wird in der Schleife Funktion B aufgerufen, der Thread B startet. Mit Beendigung von Funktion B wird auch Thread B beendet.

Der Einfachheit halber heißen alle Threadvariablen oThread. Sind alle LOCALs in den jeweiligen Funktionen.

Fehlt noch was?

Jan
Hallo Jan, dass hört sich ja ganz anders an....
Entweder Du wartest in Thread A, bis Thread B nicht mehr aktiv ist (=beendet) oder Du wartest in Thread A auf ein Signal, bis Thread A weiter arbeiten kann. Das Signal kann dann in der Funktion B am Ende oder auch nach Beendigung von Thread B ausgelöst werden :-)

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Tja, so weit bin ich auch schon gewesen. Wenn ich jetzt noch wüßte, wie ich das mache, dann wäre ich glücklich.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von UliTs »

Jan hat geschrieben:OK, also noch einmal von vorne. Noch einmal.

Es gibt eine Funktion A. Diese startet Thread A. In Thead A gibt es eine Schleife, die ruft Funktion B auf, diese Thread B. Sobald Funktion B und damit Thread B beendet sind, geht es wieder zurück in Thread A und die Schleife. Funktion B und damit Thread B werden so oft aufgerufen und beendet, wie die Schleife das vorgibt.

Fehlt noch was?

Jan
Ich glaube, dass kannst Du nicht meinen! Da gibt es ja keinen Wartezustand! Die Schleife in Thread A wartet IMMER, bis Funktion B beendet wurde.

Code: Alles auswählen

FOR I := 1 to N
   B()              // Danach geht es erst weiter, wenn B beendet wurde! :-)
NEXT I
Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von UliTs »

Noch etwas: das Synchronisieren von 2 Threads macht nur dann Sinn, wenn beide gleichzeitig laufen und zumindest ein Thread von dem anderen abhängig ist.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von Jan »

Meine ganz praktische Erfahrung sagt mir etwas ganz anderes. Funktion B und damit Thread B wird in der Schleife in Thread A mehrfach parallel aufgerufen. Ich kann das im Moment nur umgehen, indem ich nach dem Aufruf von Funktion B ein Wait(40) einbaue. Ich muß also die Schleife zwingen, vor dem nächsten Aufruf von Funktion B eine Pause einzulegen. Was aber nicht der Sinn der Sache sein kann.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Jan hat geschrieben:Sobald Funktion B und damit Thread B beendet sind, geht es wieder zurück in Thread A und die Schleife.
Hallo Jan,
es mag sein, dass du dich nur falsch ausdrückst, ABER SO STIMMT DAS NICHT !
Ein Thread wird nicht beendet nur weil die aufrufende Funktion beendet wurde.
Natürlich kannst du in der Funktion B warten bis der Thread B beendet ist, aber das schreibt sich anders ;-)

Hier ein Beispiel, sieh es dir genau an, BEIDE UHREN werden angezeigt, auch wenn die Funktion schon beendet wurde.

Code: Alles auswählen

#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "inkey.ch"
procedure main()

    cls
    @ 1,1 say "Start von Hauptprogramm - ESC = Ende"

    StarteThread()
    // die Funktion ist zu Ende, der Thread nicht !
    do while inkey(1) # K_ESC
       @10,1 say "Im Hauptprogramm "+time()
    enddo

    quit  // nur QUIT schließt alle offenen Threads !

return

function StarteThread()
   local oThread
   oThread := Thread():new()
   @ 6,1 say "Start von Funktion StarteThread() "+time()
   @ 7,1 say "Hier zeigt der Thread die Uhrzeit an solange er läuft:" color "W+/R"
   @ 8,1 say "Ende  von Funktion StarteThread() "+time()
   oThread:start( "showTime", 7, 60 )
return nil

PROCEDURE ShowTime( nRow, nCol )
   DO WHILE .T.
      DispOutAt( nRow, nCol, Time() )
      Sleep(100)
   ENDDO
RETURN
Threads sind eine verzwickte Sache. Nur das Programmende erzwingt ein Ende aller noch laufenden Threads,
wobei man gut überlegen muss, ob man einen noch laufenden Thread einfach mit QUIT abwürgen darf.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread warten lassen

Beitrag von brandelh »

Jan hat geschrieben:Meine ganz praktische Erfahrung sagt mir etwas ganz anderes. Funktion B und damit Thread B wird in der Schleife in Thread A mehrfach parallel aufgerufen.
Hallo Jan,

das bestätigt meinen obigen Verdacht, du hast da falsche Schlüsse gezogen !

Code: Alles auswählen

For x := 1 to 200
     inkey(0)  // kann jede eigene Funktion sein ! Dies hier wartet auf einen Tastendruck.
NEXT 
Der Aufruf einer Funktion BLOCKIERT IMMER bis diese beendet wurde !
Das Starten eines neuen Threads, dauert einige Millisecunden oder weniger, dann kann die Funktion beendet werden.
Der Thread selbst läuft solange weiter bis er selbst beendet wird !
Deine Funktion blockiert also schon, aber nicht lange - INKEY(40) hilft da nix, denn es könnte länger und kürzer dauern !
Dennoch hast du alle Threads erzeugt (so 100 pro Sekunde sind schon drinn denke ich) bevor auch nur einer beendet wird.
Gruß
Hubert
Antworten