Entwickler-Ecke
Sonstiges (Delphi) - Threads Synchronize
Lenovo23456 - Do 23.11.17 12:48
Titel: Threads Synchronize
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
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
public
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 - 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
Symbroson - Do 23.11.17 13:48
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; protected procedure Execute; override; public constructor Create; procedure DoProcess; end;
var Form7: TForm7; ID: integer; 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; 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); StartItem.Start; end;
procedure TForm7.Button3Click(Sender: TObject); var StoppItem: TThreadItem; Thread: TMyThread; begin StoppItem := ThreadL.GetItems(ID); StoppItem.Stopp; end; |
Lenovo23456 - 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 - Do 23.11.17 17:16
Lenovo23456 hat folgendes geschrieben : |
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?
Lenovo23456 hat folgendes geschrieben : |
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.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!