Autor Beitrag
sPeeD2k5
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72



BeitragVerfasst: Do 16.07.09 09:03 
So nachdem ich mir einige grundlegende Tutorials angeschaut habe, habe ich versuch meinen Portscanner threadfähig zu machen. Das ganze funktioniert auch solange ich nichts speichern will, wofür ich ja die Synchronisation brauche. Allerdings haut die nicht so recht hin, obwohl ich einen kritischen Abschnitt eingebaut habe, wo ja andere Threads nicht drauf zugreifen können, wenn einer Thread gerade in diesem Bereich ist.. ALlerdings bekomm ich immernoch Zugriffsverletzungen und weiß nicht so recht warum, hoffe ihr könnt mir helfen.


ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
unit UThread;

interface

uses
  Classes,
  dialogs,
  sysutils,
  uScanner,
  SyncObjs;
type
TBinFertig = procedure(const Content: Stringof object;

 myThread = class(TThread)





  private
    FBinFertig: TBinFertig;
    FBufferCritSect: TCriticalSection;
    //procedure SyncBinFertig;
    procedure SyncBinFertig;
  protected
    procedure Execute; override;
   public
    property BinFertig: TBinFertig read FBinFertig write FBinFertig;
    procedure FormCreate(Sender: TObject);
  end;

var i :integer = 0;
result1 : string;
kritischerAbschnitt: TCriticalSection;

implementation

{ Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen
  nur in einer Methode namens Synchronize aufgerufen werden, z.B.

      Synchronize(UpdateCaption);

  und UpdateCaption könnte folgendermaßen aussehen:

    procedure mythread.UpdateCaption;
    begin
      Form1.Caption := 'Aktualisiert in einem Thread';
    end; }


{ mythread }

procedure mythread.FormCreate(Sender: TObject);

begin
 kritischerAbschnitt :=TCriticalSection.Create;
end;

procedure mythread.SyncBinFertig;
var blub :tstringlist;
begin
  FBufferCritSect.Enter;
  blub := tstringlist.Create;
  blub.LoadFromFile('blub.txt');
  blub.Add(result1);
  blub.SaveToFile('blub.txt');
  FBufferCritSect.Leave;

end;


procedure mythread.Execute;
var result :string;
blub : tstringlist;
begin
try
  randomize;


  if scantcpport('127.0.0.1',21+i) = true then
    begin
      result1 := 'port '+inttostr(21+i)+' offen';

    end
    else
    begin
     result1 := 'port '+inttostr(21+i)+' closed';

    end;

   inc(i);
   //blub.SaveToFile('blub'+inttostr(random(100))+'.txt');
  //showmessage('thread');
  //SyncBinFertig(result);
  terminate;
  Synchronize(SyncBinFertig);
finally

end;
end;

end.
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Do 16.07.09 09:41 
Du hast deine CriticalSection als Private Variable - da bringt sie nichts, weil ja jeder Thread eine eigene erzeugt.
Critical Sections müssen immer global erreichbar sein, und darf es somit auch nur einmal geben.

Du hast zwar eine globale - diese wird aber bei jedem Thread Create überschrieben, und außerdem nie verwendet.

Sonstiges:
a) Schau dir mal an, was ein Constructor ist
b) Du gibst deine Stringliste nicht frei. Schau dir noch try ... finally an
c) im execute: ein try..finally Block, wobei finally leer ist macht wenig Sinn.

Edit:
d) Gewöhn dir den Vergleich auf = true direkt wieder ab
e) Du greifst von mehreren Threads aus auf die Variable i zu. Selbst das kann, ohne Synchronisierung, schon zu komischen Effekten führen.

_________________
PROGRAMMER: A device for converting coffee into software.
sPeeD2k5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72



BeitragVerfasst: Do 16.07.09 09:54 
So hab jetzt mal kleine Veränderungen vorgenommen und es scheint zu funktionieren... hab ich trotzdem noch irgndwo etwas übersehen?

ausblenden volle Höhe 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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
unit UThread;

interface

uses
  Classes,
  dialogs,
  sysutils,
  uScanner,
  SyncObjs;
type
TBinFertig = procedure(const Content: Stringof object;

 myThread = class(TThread)





  private
    FBinFertig: TBinFertig;

    //procedure SyncBinFertig;
    procedure SyncBinFertig;
  protected
    procedure Execute; override;
   public
    //FBufferCritSect: TCriticalSection;
    kritischerAbschnitt: TCriticalSection;
    property BinFertig: TBinFertig read FBinFertig write FBinFertig;
    procedure FormCreate(Sender: TObject);
    constructor Create;
  end;

var i :integer = 0;
result1 : string;
//kritischerAbschnitt: TCriticalSection;

implementation

constructor mythread.Create;
begin
  inherited Create(true);
  kritischerAbschnitt :=TCriticalSection.Create;
end;

{ Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen
  nur in einer Methode namens Synchronize aufgerufen werden, z.B.

      Synchronize(UpdateCaption);

  und UpdateCaption könnte folgendermaßen aussehen:

    procedure mythread.UpdateCaption;
    begin
      Form1.Caption := 'Aktualisiert in einem Thread';
    end; }


{ mythread }

procedure mythread.FormCreate(Sender: TObject);

begin
 //kritischerAbschnitt :=TCriticalSection.Create;
end;

procedure mythread.SyncBinFertig;
var blub :tstringlist;
begin
  kritischerabschnitt.Enter;
  try
    blub := tstringlist.Create;
    blub.LoadFromFile('blub.txt');
    blub.Add(result1);
    blub.SaveToFile('blub.txt');
  finally
  blub.free;
  kritischerabschnitt.Leave;
  end;



end;


procedure mythread.Execute;
var result :string;
blub : tstringlist;
begin
try
  randomize;


  if scantcpport('127.0.0.1',21) = true then
    begin
      result1 := 'port '+inttostr(21)+' offen';

    end
    else
    begin
     result1 := 'port '+inttostr(21)+' closed';

    end;

   
   //blub.SaveToFile('blub'+inttostr(random(100))+'.txt');
  //showmessage('thread');
  //SyncBinFertig(result);

finally
  terminate;
  Synchronize(SyncBinFertig);
end;
end;

end.
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Do 16.07.09 10:03 
Du erzeugst immer noch für JEDEN Thread eine eigene CS. So macht das Ding keinen Sinn.
Nimm eine globale, erzeug diese z.b. im Aufrufenden Formular, und verwende Sie dann nur noch in den Threads.


Nochmal sonstiges:
- Relative Dateipfade sind böse
- Execute: Wieso das terminate? Der Thread ist doch danach eh zu Ende.
- Execute: Im finally Block noch die Speichern Prozedur aufzurufen halte ich für... gewagt.

_________________
PROGRAMMER: A device for converting coffee into software.
sPeeD2k5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72



BeitragVerfasst: Do 16.07.09 10:19 
wie soll ich die im aufrufenden Forumal erzeugen? Wenn ich in diesem Formular

ausblenden Delphi-Quelltext
1:
thread.kritischerAbschnitt := TCriticalSection.Create;					


sagt er mir nur dass er TCriticalSection nicht kennt...
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Do 16.07.09 10:23 
Bind die entsprechende Unit ein.

Aber wieso schon wieder "thread.kritischerAbschnitt" ?

_________________
PROGRAMMER: A device for converting coffee into software.
sPeeD2k5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72



BeitragVerfasst: Do 16.07.09 10:37 
sorry mein fehler...

Hab übersehen, dass man die Syncobjs einbinden muss ;) In dem aufrufenden Forumular habe ich jetzt folgendes zu stehn:

ausblenden Delphi-Quelltext
1:
2:
3:
kritischerAbschnitt := TCriticalSection.Create;
thread := mythread.Create;
thread.FreeOnTerminate := True;


das mit den relativen Pfaden ist mir durchaus bewusst, es war lediglich ein flüchtigkeitsfehler, da ich nur eben testen wollte, ob er etwas in die Datei schreibt ;)

Ist sonst noch etwas zu beachten?