The synchronization problem of multiple threads to access the TStringList global

On the synchronization of multiple threads to access TStringList


On the synchronization of multiple threads to access TStringList:
My idea is: copy TStringList to another TStringList variables, to achieve multiple thread synchronization accesses to TStringList variables.

The following:
Custom class:
TNodeData = Class
ID, PID, NodeText : string;
end;

Global variables:
m_List: TStringList;
m_List:= TStringList.Create;

m_cs: TCriticalSection;
m_cs:= TCriticalSection.Create;

Initialize the m_List member value:
procedure TMainForm.FormCreate(Sender: TObject);
var
NodeData: TNodeData;
qry: TASQLite3Query;
begin
...
while not qry.Eof do
begin
NodeData:= TNodeData.Create;
NodeData.ID := qry.FieldByName('ID').AsString;
pChildNodeData.PID := qry.FieldByName('PID').AsString;
pChildNodeData.NodeText := qry.FieldByName('NodeText').AsString;
m_List.AddObject(NodeData.NodeText,NodeData);
qry.Next;
end;
qry.Close;
qry.Free;
...
end;


Because have the access to the m_List in other multiple threads and the main interface thread, so want to do synchronous: my idea is to copy a copy of m_List for other threads to call.

Custom function to copy the global variable m_List:
function CopyStringListContent(ls:TStringList):boolean;
begin
try
try
m_cs.Enter;
ls.Assign(m_List);
result:= true;
finally
m_cs.Leave;
end;
except
result:= false;
end;
end;

Thread 1's m_List access: the value of m_List in the dungeon:
var
list: TStringList;
begin
...
list := TStringList.Create;
if not CopyStringListContent(list) then //A copy of the same value as the m_List TStringList new variable list.
exit;
for i:= 0 to list.Count-1 do
begin
...
list.Objects[i].Free; //After the completion of the operation to release the object local variables in list
end;
list.Free;
...
end;


Run the above code, and if in other places have access to objects in the m_List will! Because the objects in the m_List is released.
The following:
for i:= 0 to m_List.Count-1 do
begin
strNodeID := TNodeData(m_List.Objects[i]).ID; //Here we report the wrong´╝ü
strNodeText:= TNodeData(m_List.Objects[i]).NodeText;
m_List.Objects[i].Free;
end;



Question 1: the implementation of the CopyStringListContent function ls.Assign (m_List); m_List and list variable pointing to the same memory block.
And so I read the following code to copy the value of m_List,
There are more convenient way to do it? ? ?
function CopyStringListContent(ls:TStringList):boolean;
var
i:integer;
node:TNodeData;
begin
try
try
m_cs.Enter;
for i:= 0 to m_List.Count-1 do
begin
node := TNodeData.Create;
node.ID := TNodeData(m_List.Objects[i]).ID;
node.PID:= TNodeData(m_List.Objects[i]).PID;
node.NodeText:= TNodeData(m_List.Objects[i]).NodeText;
ls.AddObject(node.NodeText,node);
end;
result:= true;
finally
m_cs.Leave;
end;
except
result:= false;
end;
end;


Question 2: ask you said synchronization method to achieve the same global variables in the multiple threads.

Started by Berger at February 06, 2016 - 4:13 PM

Using TThreadList

Posted by Beau at February 11, 2016 - 4:51 PM

Question 2: ask you heroes, for the synchronization of access to a global variable in multiple threads? ? ?

Posted by Berger at February 13, 2016 - 5:24 PM

A mutex or critical areas, search, all over the sky is

Posted by Beau at February 17, 2016 - 5:52 PM

But I am in multiple threads of different functions are used to m_List, and is always dead loop to read the m_List.
The following code:
while not terminated do
begin
for i:= 0 to m_List.Count-1 do
begin
The value of TNodeData (m_List.Objects[i]).ID used to do some work.
end;
end;

When the other thread's cycle of the call to m_List, if m_List is the main interface operation to delete a member, then the above code is not there may be wrong?
Dead cycle like this, I can't add m_cs.Enter and m_cs.Leave to protect, because will make this cycle will always occupy the m_List.

Posted by Berger at February 28, 2016 - 6:32 PM

In the D2010 version, you can use ThreadVar to declare a thread variables. Or use a mutex to access.

Posted by Ogden at January 07, 2017 - 3:37 PM

LZ should have a look the related principle of thread synchronization
If you do not want to see, if your thread to that variable is read but not write, can not be synchronized, but is likely to affect change update.

In addition to to LS threadvar D5, at least in the beginning, not necessarily d2010, D5 never used before is not know. But the role of threadvar and LZ needs no what relationship, threadvar statement variables is used to store different threads in different values.

Posted by Beau at January 12, 2017 - 3:17 PM