| Autor |
Beitrag |
ralfi
      
Beiträge: 153
|
Verfasst: Mi 26.11.03 11:18
Hallo!
In meinem Programm habe ich einige Threads, jeder von dennen separat erstellt wurde (also kein Array of Threads oder so was). Jeder Thread macht irgendwas anderes.
1. Wie kann ich zu jedem Moment sehen, wieviele Threads z. Z. aktiv sind?
2. Wie kann ich es so synchronisieren, dass z. B. nicht mehr als 5 Threads glecihzeitig laufen dürfen und alle andere warten?
Danke! 
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Mi 26.11.03 11:23
Vor dem Erstellen eines neuen Threads erhöhst du eine Variable "AktiveThreads" um 1 und im Thread destruktor Destroy ziehst du wieder 1 ab. Somit steht in AktiveThread die Anzahl der gerade laufenden Threads (vorausgesetzt deine Threads beenden sich nachdem Execute beendet ist und warten nicht in Execute auf eine neue Aufgabe). Ansonsten wird es etwas komplizierter, da du den Zugriff auf "AktiveThreads" mit CriticalSections regeln müsstest.
_________________ Ist Zeit wirklich Geld?
|
|
ralfi 
      
Beiträge: 153
|
Verfasst: Mi 26.11.03 13:40
In allen Threads werden die Aufgaben wiederholt, solange Terminated=false.
Quelltext 1: 2:
| while not terminated do DoWork |
Was muss ich in diesem Fall?
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Fr 28.11.03 16:00
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:
| uses tlhelp32;
function GetThreadCount:integer; var pe32:TProcessEntry32; Pid,Hnd:Cardinal; begin Result:=0; Hnd:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS,0); if Hnd=INVALID_HANDLE_VALUE then exit; try GetWindowThreadProcessID(Application.Handle,@Pid);
pe32.dwSize:=SizeOf(ProcessEntry32); if Process32First(Hnd,pe32)=true then repeat if Pid=pe32.th32ProcessID then begin Result:=pe32.cntThreads-1; exit; end; until not Process32Next(Hnd,pe32); finally CloseHandle(Hnd); end; end; | Funktioniert wunderbar.
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 28.11.03 17:04
Was soll das exit in der if-Bedingung? So wird dein Handle nie geschlossen. Und warum cntThreads-1? Hast du gar keinen eigenen Thread erstellt, liefert dir das 0 und das stimmt nicht, der Hauptthread ist ja auch noch da. Und wozu die Schleife? Übergibst du bei CreateToolHelp32Snapshot als zweiten Parameter 0, hast du schon einen Hanlde auf deinen eigenen Prozess.
So würde es bei mir aussehen:
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:
| uses tlhelp32;
function GetThreadCount(Handle: THandle): integer; var pe32: TProcessEntry32; SnapShot: THandle; NumThreads: Cardinal; begin NumThreads := 0; SnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); if SnapShot <> INVALID_HANDLE_VALUE then try pe32.dwSize := SizeOf(ProcessEntry32); if Process32First(SnapShot, pe32) then NumThreads := pe32.cntThreads; finally CloseHandle(SnapShot); end; result := NumThreads; end;
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(IntToStr(GetThreadCount(Handle))); end; |
Zuletzt bearbeitet von Luckie am Sa 29.11.03 15:14, insgesamt 1-mal bearbeitet
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Sa 29.11.03 14:32
| Luckie hat folgendes geschrieben: | | if Process32First(SnapShot, pe32) = true then |
Und viel Spaß mit Delphi < 5.
Man sollte nicht auf True testen, sondern einfach
Delphi-Quelltext 1:
| if Process32First(SnapShot, pe32) then |
schreiben, dann wird auf <> 0 getestet, was bei WinAPI Funktionen besser ist.
_________________ Ist Zeit wirklich Geld?
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 29.11.03 15:14
Führt das bei Delphi < 5 echt zu Problemen? Uiuiuiui, gleich mal verbesseren. danke für den Hinweis, ist noch vom Copy and paste übriggeblieben. 
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Sa 29.11.03 17:38
| Luckie hat folgendes geschrieben: | | Was soll das exit in der if-Bedingung? So wird dein Handle nie geschlossen. Und warum cntThreads-1? |
Durch das exit springt Delphi automatisch zum finally-Block, wo das Handle geschlossen wird! cntThreads-1, weil ja hier nur das vorkommen von selbsterstellten TThreads in Erfahrung gebracht werden muss. Wobei dein Code natürlich trotzdem besser ist 
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 29.11.03 17:48
Falsch. Ein exit verlässt die ganze Prozedur. Mit einem break kommst du aus der Schleife raus! Aber die Schleife ist immer noch Blödsinn.
| Zitat: |
weil ja hier nur das vorkommen von selbsterstellten TThreads in Erfahrung gebracht werden muss
|
Ja, aber dann würde ich die Anzahl der Threads nachher abziehen. Denn so ist die Funktion universell einsetztbar und die Wiederverwendbarkeit höher.
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Sa 29.11.03 18:05
| Delphi Hilfe hat folgendes geschrieben: | | Note: Exit passes control away from the current procedure, not merely the current block. But Exit does not violate the flow of control dictated by a try..finally construct; if Exit is called inside the try clause, the finally clause is still executed. |
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Sa 29.11.03 18:06
| Luckie hat folgendes geschrieben: | | Falsch. |
Das Exit geht alle finally-Blöcke (der höheren Ebenen) durch. Man muss dort nur einen Breakpoint setzen und schon bleibt der Debugger im finally-Teil stehen.
_________________ Ist Zeit wirklich Geld?
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 29.11.03 18:14
Oh. Wieder was gelernt. 
|
|