Autor Beitrag
Lenovo23456
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Do 23.11.17 12:48 
Hi, ich habe ein paar Probleme mit dem Synchronisieren.

Ich habe mehrere Threads angelegt und will in einem Memo sehen welcher gerade läuft.
Seit dem ich die Synchronize Methode eingebaut habe, läuft das nicht mehr wie gewollt.

Hier mal mein Code

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:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
unit Unit7;

 

interface

 

uses

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,

  System.Classes, Vcl.Graphics,

  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.ExtCtrls;

 

type

  TForm7 = class(TForm)

    Start: TButton;

    Button3: TButton;

    ListBox1: TListBox;

    Label1: TLabel;

    Memo1: TMemo;

    procedure StartClick(Sender: TObject);

    procedure FormCreate(Sender: TObject);

    procedure ListBox1Click(Sender: TObject);

    procedure Button3Click(Sender: TObject);

 

  private

    { Private-Deklarationen }

  public

    { Public-Deklarationen }

  end;

 

  TMyThread = class(TThread)

 

  protected

    procedure Execute; override;

  public

 

    constructor Create;

    procedure DoProcess;

 

  end;

 

  TThreadItem = class(TCollectionItem)

 

  public

    FThreadItem: TMyThread;

    constructor Create(ACollection: TCollection); override;

    procedure Start();

    procedure Stopp;

 

  published

  end;

 

  TThreadlist = class(TCollection)

  private

 

    procedure SetItems(Index: integer; AValue: TThreadItem);

  public

    constructor Create;

    function GetItems(Index: integer): TThreadItem;

    function AddEx: TThreadItem;

    property Items[Index: integer]: TThreadItem read GetItems

      write SetItems; default;

  end;

 

var

  Form7: TForm7;

  ID, ThreadIDDD: integer;

  ThreadL: TThreadlist;

 

implementation

 

{$R *.dfm}

 

constructor TMyThread.Create;

begin

  inherited Create(True);

end;

 

constructor TThreadItem.Create(ACollection: TCollection);

begin

  inherited Create(ACollection);

  FThreadItem := TMyThread.Create;

 

end;

 

constructor TThreadlist.Create;

begin

  inherited Create(TThreadItem);

end;

 

procedure TThreadItem.Start;

begin

 

  FThreadItem.Resume;

end;

 

procedure TThreadItem.Stopp;

begin

  FThreadItem.Suspend;

end;

 

function TThreadlist.GetItems(Index: integer): TThreadItem;

begin

  result := TThreadItem(inherited Items[index]);

end;

 

procedure TThreadlist.SetItems(Index: integer; AValue: TThreadItem);

var

  T: TMyThread;

begin

  Items[Index].Assign(AValue);

end;

 

function TThreadlist.AddEx: TThreadItem;

begin

  result := inherited Add as TThreadItem;

end;

 

procedure TMyThread.Execute;

 

begin

  while not Terminated do

  begin

    sleep(100);

    synchronize(DoProcess);

  end;

 

end;

 

procedure TMyThread.DoProcess;

 

begin

 

  Form7.Memo1.Lines.Add('Thread Nr. ' + IntToStr(ThreadIDDD) + ' ' +

    DateTimeToStr(Now) + ' Uhr');

end;

 

procedure TForm7.ListBox1Click(Sender: TObject);

var

  Thread: TMyThread;

begin

  ID := integer(ListBox1.Items.Objects[ListBox1.ItemIndex])

end;

 

procedure TForm7.FormCreate(Sender: TObject);

var

  i: integer;

begin

  ThreadL := TThreadlist.Create;

  for i := 0 to 5 do

  begin

    ThreadL.AddEx;

  end;

  for i := 0 to 5 do

  begin

    if Assigned(ThreadL) then

      ListBox1.Items.AddObject('Thread Nr. ' + IntToStr(i), TObject(i));

 

  end;

 

end;

 

procedure TForm7.StartClick(Sender: TObject);

var

  Thread: TMyThread;

  StartItem: TThreadItem;

begin

  ThreadIDDD := ID;

  StartItem := ThreadL.GetItems(ThreadIDDD);

  StartItem.Start;

 

end;

 

procedure TForm7.Button3Click(Sender: TObject);

var

  StoppItem: TThreadItem;

  Thread: TMyThread;

begin

  ThreadIDDD := ID;

 

  StoppItem := ThreadL.GetItems(ThreadIDDD);

  StoppItem.Stopp;

 

end;
end.


Momentan seh ich in der Memo dann immer nur einen einzigen Thread laufen. Wahrscheinlich liegt es daran das durch Synchronize nur ein Thread auf das Memo schreiben darf oder ?
Wie kann ich es machen, das sie abwechselnd darauf zugreifen dürfen?
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 382
Erhaltene Danke: 67

Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
BeitragVerfasst: Do 23.11.17 13:31 
Dein Programm ist soweit richtig, nur deine Ausgabe ist fehlerhaft. Wenn du das Intervall von 100ms auf 1000 setzt merkst du das auch.
Das liegt daran, dass du ThreadIDDD global definierst und jeder Thread diese Variable ausgibt. Wenn du also diese änderst, schreiben alle Threads diesen neuen Wert.
Du musst also dem Thread-Objekt eine ID Variable hinzufügen bzw dessen Index in deiner ThreadList ausgeben. ;)

LG,
Symbroson

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)


Zuletzt bearbeitet von Symbroson am Do 23.11.17 13:56, insgesamt 1-mal bearbeitet
Symbroson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 382
Erhaltene Danke: 67

Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
BeitragVerfasst: Do 23.11.17 13:48 
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:
  TMyThread = class(TThread)
    ThreadIDDD: integer; //ThreadIDDD hinzugefügt
  protected
    procedure Execute; override;
  public
    constructor Create;
    procedure DoProcess;
  end;

{...}

var
  Form7: TForm7;
  ID: integer; //ThreadIDDD entfernt
  ThreadL: TThreadlist;

{...}

procedure TForm7.FormCreate(Sender: TObject);
var i: integer;
begin
  ThreadL := TThreadlist.Create;
  for i := 0 to 5 do
    ThreadL.AddEx.FThreadItem.ThreadIDDD := i; //ThreadIDDD zuweisen

  for i := 0 to 5 do
    if Assigned(ThreadL) then
      ListBox1.Items.AddObject('Thread Nr. ' + IntToStr(i), TObject(i));
end;

procedure TForm7.StartClick(Sender: TObject);
var
  Thread: TMyThread;
  StartItem: TThreadItem;
begin
  StartItem := ThreadL.GetItems(ID); //ID statt ThreadIDD
  StartItem.Start;
end;

procedure TForm7.Button3Click(Sender: TObject);
var
  StoppItem: TThreadItem;
  Thread: TMyThread;
begin
  StoppItem := ThreadL.GetItems(ID); //ID statt ThreadIDD
  StoppItem.Stopp;
end;

_________________
most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
Lenovo23456 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Do 23.11.17 14:40 
Ahh hab ich mir schon gedacht, dass es mit dem zusammenhängt.
Ich hab mir dann auch eine Variable in TMyThread erstellt, aber eben dann falsch angewandt. Jetzt funktioniert es aber, vielen Dank.
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Do 23.11.17 17:16 
user profile iconLenovo23456 hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe mehrere Threads angelegt und will in einem Memo sehen welcher gerade läuft.


Dieser Ansatz ist fehlerhaft.

Es ist ja gerade das Wesen von Windows, allgemein von Multitaskingbetriebsprogrammen, möglichst viel möglichst gleichzeitig laufen zu lassen (bis zu einem bestimmten Maße jedenfalls).

Es läuft nicht brav erst der eine und dann der andere Thread, sondern i.d.R. mal mehr, mal weniger der Threads gleichzeitig / simultan.

Zudem entscheidet Windows viele, ja unzählige Male in jeder Sekunde, welchen Thread es stoppt und welchen es weiterlaufen läßt.

Wie wollte man so etwas sinnvoll anzeigen?

user profile iconLenovo23456 hat folgendes geschrieben Zum zitierten Posting springen:
Seit dem ich die Synchronize Methode eingebaut habe, läuft das nicht mehr wie gewollt.


Natürlich, denn Synchronize ist der Engpaß, neudeutsch: Flaschenhals.

Die Thread stehen alle Schlange, mit dem VCL-Thread in Kontakt treten zu dürfen, und solange stehen sie still. Wie bei einer menschlichen Warteschlange eben.