Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TThreadList and Synchronize in theads

974 views
Skip to first unread message

column

unread,
Oct 22, 2008, 12:37:57 PM10/22/08
to
Hello,

I have strange situation. My ThreadList doesn't unlock in Synchronise
method. Main form is frozen. It Works fine without synchronisation.
But I need sychronise it because I need to operate with another data
that is not in LockList.

procedure TCm.Execute;
var i: integer;
begin
inherited;
while not terminated do
begin
for i := 0 to Clients.LockListt('Execute 1').Count - 1 do
begin
if TData(Clients.LockListt('Execute 2').Items[i]).Requested=
false then
begin
TData(Clients.LockListt('Execute 3').Items[i]).Requested:=
WriteString( TData(Clients.LockListt('Execute
4').Items[i]).Request.ToString(xml));
end;
end;
if bef<>aft then Synchronize(DoOnNewData);
end;

end;


........................................................................
Synchronised procedure:
........................................................................
for i:=0 to Clients.LockListt('ProceedData 1 ').Count-1 do
begin
if TData(Clients.LockListt('ProceedData
2').Items[i]).Request.AMOUNT= v.AMOUNT then
TData(Clients.LockListt(('ProceedData 3')).Items[i]).Answer.Assign(v);
end;

Thank You

rt15

unread,
Oct 23, 2008, 7:12:55 AM10/23/08
to
Hello (And sorry for my horrible english),

The "Synchronize" methode is used to make the main thread running the
method passed as arguement to "Synchronize".

The main thread is also the thread that manage VCL component. If this
thread is busy, forms are frozen.

Maybe your threads call Synchronize numerous times per seconds ? How
is your CPU when your window is frozen ?

However, if you don't interact with VCL in your synchronized method,
you should use a different synchronization method, and let the main
thread do his job.

For example, you could use a critical section. A critical section is a
portion of code that can be executed by only one thread at the same
time.

Delphi, in some version, provide TCriticalSection. If you cannot use
TCriticalSection, you can use Win32 critical section, which is very
simple to use.

Here is some help about it :
http://msdn.microsoft.com/en-us/library/ms682530.aspx

There are 4 functions : init, enter, leave and delete, and a structure
that must be common for all calls for one critical section.

Here are more help for Delphi :
http://www.delphicorner.f9.co.uk/articles/op4.htm

Anyway, your problem is quite strange...

column

unread,
Oct 24, 2008, 4:07:17 AM10/24/08
to
> > Thank You- Slėpti cituojamą tekstą -
>
> - Rodyti cituojamą tekstą -


Strange problem appears when LockList adds new object into list. After
this procedure is done in one thread another thread can't lock list.
First thread unlocks list.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient,
IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, ExtCtrls,my_utils,
my_types;

type TBufferDataa = Procedure of object;


type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure log(s: string);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ProceedDataa ;
procedure Button2Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;


type TTs =class (TThread)
private
FOnNewData: TBufferDataa;

published
procedure Execute; override;
constructor Create;
destructor Destroy;override;
procedure DoOnNewData;

published
property OnNewData: TBufferDataa read FOnNewData write FOnNewData;

end;


type TData = class
Requested: boolean;
Request: String;
Answer: String;
constructor Create;
Destructor Free;
end;

type TClients = class( TThreadList)
Function LockListt(s: string):TList;
procedure UnlockListt(s: string);

end;

var
Form1: TForm1;
Clients : TClients;
Ts: TTs;
v: TData;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
Clients.LockListt('Button1Click').Add(v);
Clients.UnlockListt('Button1Click');
end;

procedure TForm1.Button2Click(Sender: TObject);
var i: integer;
begin
for i := 0 to Clients.LockListt('Button2Click').Count - 1 do
begin

DebugWindow(TData(Clients.LockListt('Button2Click').Items[i]).Request );
end;
Clients.UnlockListt('Button2Click');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
v.Free;
Ts.Free;
Clients.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
v:=TData.Create;
Clients:= TClients.Create;

Ts:=TTs.Create;
Ts.OnNewData:= ProceedDataa;
Ts.Resume;

end;

procedure TForm1.log(s: string);
begin
memo1.Lines.Add(s);
debugwindow(s);
end;


procedure TForm1.ProceedDataa;
var i: integer;
begin


for i:=0 to Clients.LockListt('ProceedData 1 ').Count-1 do
begin

TData(Clients.LockListt('ProceedData 2').Items[i]).Request:=
'RequestData';
end;
Clients.UnlockListt('ProceedData 1');
end;


{ TData }

constructor TData.Create;
begin
requested:= false;
Request:='';
Answer:='';
end;

destructor TData.Free;
begin
end;

{ TClients }

function TClients.lockListt(s: string): TList;
begin
DebugWindow('locking by '+s);
result:= LockList;
DebugWindow('locked by '+s);
end;

procedure TClients.UnlockListt(s: string);
begin
DebugWindow('unlocking by '+s);
self.UnlockList;
DebugWindow('unlocked by '+s);
end;

{ TTs }

constructor TTs.Create;
begin
inherited Create(true);

end;

destructor TTs.Destroy;
begin
inherited;

end;

procedure TTs.DoOnNewData;
begin
if assigned(OnNewData) then OnNewData;

end;

procedure TTs.Execute;


var i: integer;
begin
inherited;
while not terminated do
begin

//Clients.LockListt('Execute 0').Add(v);
Clients.UnlockListt('Execute 0');

for i := 0 to Clients.LockListt('Execute 1').Count - 1 do
begin
if TData(Clients.LockListt('Execute 2').Items[i]).Requested=
false then
begin
TData(Clients.LockListt('Execute 3').Items[i]).Requested:=

true;
end;
end;
Clients.UnlockListt('Execute 1');

Synchronize(DoOnNewData);

sleep(1000);

end;
end;

end.
log('Status '+AStatusText);
end;

procedure TForm1.ClWork(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Integer);
begin
memo1.Lines.Add('Work');
end;

procedure TForm1.ClWorkBegin(ASender: TObject; AWorkMode: TWorkMode;
AWorkCountMax: Integer);
begin
memo1.Lines.Add('WorkBegin');
end;

procedure TForm1.ClWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
memo1.Lines.Add('WorkEnd');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
v.Free;
Ts.Free;
Clients.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
v:=TData.Create;
Clients:= TClients.Create;

Ts:=TTs.Create;
Ts.OnNewData:= ProceedDataa;
Ts.Resume;

end;

procedure TForm1.log(s: string);
begin
memo1.Lines.Add(s);
debugwindow(s);
end;


procedure TForm1.ProceedDataa;
var i: integer;
begin


for i:=0 to Clients.LockListt('ProceedData 1 ').Count-1 do
begin

TData(Clients.LockListt('ProceedData 2').Items[i]).Request:=
'RequestData';
end;
Clients.UnlockListt('ProceedData 1');
end;


{ TData }

constructor TData.Create;
begin
requested:= false;
Request:='';
Answer:='';
end;

destructor TData.Free;
begin
end;

{ TClients }

function TClients.lockListt(s: string): TList;
begin
DebugWindow('locking by '+s);
result:= LockList;
DebugWindow('locked by '+s);
end;

procedure TClients.UnlockListt(s: string);
begin
DebugWindow('unlocking by '+s);
self.UnlockList;
DebugWindow('unlocked by '+s);
end;

{ TTs }

constructor TTs.Create;
begin
inherited Create(true);

end;

destructor TTs.Destroy;
begin
inherited;

end;

procedure TTs.DoOnNewData;
begin
if assigned(OnNewData) then OnNewData;

end;

procedure TTs.Execute;


var i: integer;
begin
inherited;
while not terminated do
begin

//Clients.LockListt('Execute 0').Add(v);
Clients.UnlockListt('Execute 0');

for i := 0 to Clients.LockListt('Execute 1').Count - 1 do
begin
if TData(Clients.LockListt('Execute 2').Items[i]).Requested=
false then
begin
TData(Clients.LockListt('Execute 3').Items[i]).Requested:=

true;
end;
end;
Clients.UnlockListt('Execute 1');

Synchronize(DoOnNewData);

sleep(1000);

end;
end;

end.

0 new messages