Hallo,
ich habe eine Konsolenanwendung mit einem Record in einem Array, welches von diversen Threads verwendet werden soll.
Sowohl lesen als auch schreiben.
Das Array wird von einem eigenen Thread abgearbeitet und von anderer Seite wieder aufgefüllt.
Es ist also eine Queue.
Der Queue Thread sieht wie folgt aus:
Delphi-Quellcode:
type Tsend_entry=record
Frame:TWebSocketFrame;
recipients:THttpServerConnectionIDDynArray;
end;
var
send_queue:array of Tsend_entry;
procedure DeleteArrayElement(const AIndex: Integer);
begin
Move(send_queue[AIndex + 1], send_queue[AIndex], SizeOf(send_queue[0]) * (Length(send_queue) - AIndex - 1)); //Dahinterliegende Daten aufrücken
SetLength(send_queue, Length(send_queue) - 1); // Länge kürzen
end;
procedure TQueueSendThread.Execute;
begin
while not stop_thread do
begin
sleep(100);
if high(send_queue)>=0 then
if not array_lock then
begin
array_lock:=true; //beides muss zusammen ausgeführt werden
sleep(10);
server.WebSocketBroadcast( send_queue[0].frame,send_queue[0].recipients);
DeleteArrayElement(0);
array_lock:=false;
end;
end;
end;
Die Threads zum Auffüllen berücksichtigen den Arraylock ebenfalls.
Theoretisch ist das Array also gesperrt wenn es in schreibender Verwendung ist.
Dennoch habe ich mit Problemen zu kämpfen, wo ich sagen würde, das es mit dem Timing zusammen hängt.
Denn zwischen prüfung ob der Lock gesetzt ist und anschließenden setzen, könnte ein anderer Thread zuvorkommen.
Zuvor hatte ich folgendes versucht:
Delphi-Quellcode:
server.WebSocketBroadcast( send_queue[0].frame,send_queue[0].recipients);
TThread.Synchronize(nil, procedure
begin
DeleteArrayElement(0);
end);
Aber das klappte gar nicht erst.
Wie kann ich den Zugriff threadsicher gestalten?
Oder liegt es vielleicht auch schon daran, das ich den Arraylock nur beim schreiben setze?