Threads nach ablauf zerstören?

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Threads nach ablauf zerstören?

Beitrag von ab-software »

Hallo,

ich habe folgendes Problem. Wir migrieren zurzeit von Clipper zu Xbase. Um unseren Kunden auch aus dem alten Clipperprogramm schon neue Funktionen zur Verfügung stellen zur können schreiben wir aus Clipper Anfragen in eine Datenbank. Im Hintergrund läuft auf den Rechnern dann eine Xbase Applikation die diese Anfragen auswertet und die entsprechenden Xbase Programme startet , Rückgaben werden einfach wieder in die Datenbank geschrieben.

Das Programm das im Hintergrund läuft ruft alle paar Sekunden (über einen Zeitgesteuerten Thread) eine Funktion auf die nachguckt ob neue Anfragen da sind. Ist eine neue Anfrage da wird ein neuer Thread gestartet. Indem wird dann die entsprechende Funktion (über DLLs) gestartet. Problem ist jetzt das mein Programm bei jedem dieser Functionsaufrufe mehr Speicher braucht (ca. 4KB pro Aufruf). Lasse ich den 2. Thread weg und rufe die Funktion direkt auf , wird kein zusätzlicher Speicher mehr verbraucht.

Muss ich den zusätzlich gestarteten Thread selbst zerstören oder zerstört dieser sich nach Ablauf selbst? Wenn ja wie kann ich ihn zerstören?

Hoffe ihr könnt mir helfen, danke schonmal
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Threads nach ablauf zerstören?

Beitrag von AUGE_OHR »

hi,
ab-software hat geschrieben: Das Programm das im Hintergrund läuft ruft alle paar Sekunden (über einen Zeitgesteuerten Thread) eine Funktion auf die nachguckt ob neue Anfragen da sind. Ist eine neue Anfrage da wird ein neuer Thread gestartet. Indem wird dann die entsprechende Funktion (über DLLs) gestartet. Problem ist jetzt das mein Programm bei jedem dieser Functionsaufrufe mehr Speicher braucht (ca. 4KB pro Aufruf). Lasse ich den 2. Thread weg und rufe die Funktion direkt auf , wird kein zusätzlicher Speicher mehr verbraucht.

Muss ich den zusätzlich gestarteten Thread selbst zerstören oder zerstört dieser sich nach Ablauf selbst?

Wenn ja wie kann ich ihn zerstören?
ich fange mal mit der letzten Frage an :

LOCAL oThread
...
oThread := Thread():new()
oThread:setInterval(10)
oThread:start("EVTHREAD",oDlg,aoChild)
...
//
// set to NIL will terminate Tread
//
oThread:setInterval(NIL)

Zum Thema "mehr Speicher braucht" will ich mich jetzt nicht äussern,
aber "wie misst" du den RAM "Verbrauch" ?

Zur Konstruktion Thread/Dll laden : Da RAM heute nicht mehr das
Problem ist versuche ich immer "alles" zu laden. Auch wird dann
der "wiederholte" Zugriff schneller als von der HD.

Also statt den Thread "immer wieder" aufzurufen sollte man "im Thread"
ein "timeout" einbauen und dann das DBSEEK() machen.

Das Timeout kann man nun "sauber" in die "Thread AppEvent Loop"
einbauen wenn man den 4st. Parameter nimmt.

Code: Alles auswählen

   DO WHILE .NOT. lExit

      nEvent := xbe_None
      DO WHILE nEvent <> xbeP_Close
         nEvent := AppEvent( @mp1, @mp2, @oXbp ,6000) // 6000=60Sec

         DO CASE
            CASE nEvent = xbe_None              // timeout
      Exit                             // raus
...
         OTHERWISE
            oXbp:handleEvent( nEvent, mp1, mp2 )
         ENDCASE
      ENDDO nEvent <> xbeP_Close

      DO WHILE Look4Mail
         POP3->(DBSEEK(ID_USER+"0"))
         IF FOUND()
...
         ELSE
       EXIT
         ENDIF
      ENDDO Look4Mail
   ENDDO .NOT. lExit
gruss by OHR
Jimmy
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:

Beitrag von andreas »

Hallo,

ich hatte das gleiche Problem und habe es genauso gelöst, wie Jimmy vorgeschlagen hat: Funktion ständig im Thread laufen lassen, wo bei zum Warten Sleep() eingesetzt wird. Wenn du die Public-Variable zum Erstellen des Thread benutzt, soltest du diese nach dem Beenden bzw. Starten des Threads auf NIL setzen, wenn du diese nicht mehr brauchst. Dann wird der Thread aus dem Speicher etfernt.
Ich habe bei mir im Fenster zus. ein XBPMLE eingebaut und ein Thread laufen lassen, der die Infos über laufende Threads anzeigt. Jedem Thread habe ich einen Cargo-Wert zugewiesen, damit ich sehen kann, was das überhaupt ist. Du könntest diese zum Testen auch verwenden. Du muss die Ausgabe noch anpassen.

Code: Alles auswählen

METHOD ThreadInfoAnzeigen()
	local aInfo := {}
	local cText := ""
	

	if lTerminated
		oThreadInfo:setInterval( NIL )
	else

		bSaveError := ErrorBlock()
		ErrorBlock( {|e| Break(e)} )
		BEGIN SEQUENCE
			aInfo := ThreadInfo( THREADINFO_TID + THREADINFO_FUNCINFO + THREADINFO_TOBJ )

			IF ::einAktualisieren:getdata()

				cText := "ID / Zeile / Funktion / Name / Interval-Rest / Startcount "
				cText += CRLF+"---------------------------------------------------------------"

				FOR i := 1 TO len(aInfo)

					cText += CRLF+var2char(aInfo[i][1])+" / ";
						+var2char(aInfo[i][2])+" / "+var2char(aInfo[i][3]);
						+IIF( valtype(aInfo[i][4])=="O", IIF( isMemberVar(aInfo[i][4], "CARGO"), " / "+alltrim(var2char(aInfo[i][4]:cargo)) , " / Fehler: keine Membervariable" )  , " / Fehler: kein Objekt" );
						+IIF( valtype(aInfo[i][4])=="O", IIF( isMemberVar(aInfo[i][4], "CARGO"), " / "+alltrim(str(int(val(var2char(aInfo[i][4]:interval))/100))) + "-"+alltrim(str(int(val(var2char(aInfo[i][4]:deltatime))/100))) , " / Fehler: keine Membervariable" )  , " / Fehler: kein Objekt" );
					+IIF( valtype(aInfo[i][4])=="O", IIF( isMemberVar(aInfo[i][4], "CARGO"), " / "+alltrim(var2char(aInfo[i][4]:startcount)) , " / Fehler: keine Membervariable" )  , " / Fehler: kein Objekt" )

							
				NEXT

				::XBPMLE:setdata( cText )

			ENDIF

		RECOVER
			ErrorBlock( bSaveError )
		END SEQUENCE
		ErrorBlock( bSaveError )

	endif

RETURN self
::einAktualisieren - ist ein Checkbox, das die Aktualiesierung abschalten kann, um den Text normal lesen zu können.
Dabei solltest du beachten, dass immer ein Main-Thread vorhanden ist. Dem kannst du einen Namen folgend vergeben:

Code: Alles auswählen

ThreadObject():cargo := "Main"
Gruß,

Andreas
VIP der XUG Osnabrück
ab-software
UDF-Programmierer
UDF-Programmierer
Beiträge: 51
Registriert: Di, 18. Okt 2005 12:35
Wohnort: 41747 Viersen
Kontaktdaten:

Beitrag von ab-software »

Hallo,

danke für die Tipps funktioniert mittlerweile problemlos.

Danke :)
Antworten