Autor Beitrag
ralfi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 153



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 153



BeitragVerfasst: Mi 26.11.03 13:40 
In allen Threads werden die Aufgaben wiederholt, solange Terminated=false.

ausblenden Quelltext
1:
2:
while not terminated do
DoWork


Was muss ich in diesem Fall?
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Fr 28.11.03 16:00 
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:
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// Thread - MainThread (Application)
    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



BeitragVerfasst: 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:
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:
uses tlhelp32;

function GetThreadCount(Handle: THandle): integer;
var
  pe32: TProcessEntry32;
  SnapShot: THandle;
  NumThreads: Cardinal;
begin
  NumThreads := 0;
  SnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);  // 0: current process
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: 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
ausblenden 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



BeitragVerfasst: 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. :wink:
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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 :roll:

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: 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



BeitragVerfasst: Sa 29.11.03 18:14 
Oh. Wieder was gelernt. :P