multithreading - Critical section in service, multithreaded service -


i developed service application collecting jpeg data equipment. number of remote devices varies 1 20.

after service start creates number of threads=current number of remote devices.

every thread writing global array of records.

record:

type tdevice=record   devname:string;   ms:tmemorystream; end;  devices:array of tdevice;  cs:tcriticalsection; 

threads creation

cs:=tcriticalsection.create;  := 0 device_list_names.count-1   begin     packs[i].ms:=tmemorystream.create;     arr_ct[i]:=tclientthread.create(false,device_list_ip.strings[i],       cs,packs[i].ms);      arr_ct[i].freeonterminate:=false;     arr_ct[i].priority:=tplower;   end; 

thread destroing

for := 0 length(arr_ct)-1   begin     arr_ct[i].terminate;     arr_ct[i].waitfor;     arr_ct[i].free;   end; 

thread code

type   tclientthread = class(tthread)  private    imconnected:boolean;    flock:tcriticalsection;    faddress:string;    logpath:string;    tcpcli:tidtcpclient;    fms:tmemorystream;    procedure createsocket;    procedure getimagestreamtcp;  protected    procedure execute;override;  public    constructor create(createsuspended: boolean;const address:string;     var alock:tcriticalsection; var ams:tmemorystream);  end;  const   socketport:integer=12340;  implementation  uses globalvariables, superlog;  constructor tclientthread.create(createsuspended: boolean;const address:string;   var alock:tcriticalsection; var ams:tmemorystream); begin   inherited create(createsuspended);   flock:=alock;   fms:=ams;   faddress:=address;    imconnected:=false;    logpath:='e:\netview07\logs\'+faddress+'_'+     formatdatetime('dd-mm-yyyy',now)+'.log';    posttolog(logpath,'e:\netview07\logs\_'+             formatdatetime('dd-mm-yyyy',now)+'.log');    posttolog('thread '+faddress+' started',logpath); end;  procedure tclientthread.createsocket; begin   tcpcli:=tidtcpclient.create(nil);   tcpcli.host:=faddress;   tcpcli.port:=socketport;   tcpcli.readtimeout:=3000; end;  procedure tclientthread.getimagestreamtcp; begin   try     try       if not imconnected         begin           tcpcli.connect;           imconnected:=true;         end;       flock.enter;       fms.clear;       tcpcli.iohandler.writeln('grab');       tcpcli.iohandler.readstream(fms, -1);     except on e:exception       begin         posttolog('error on receive stream('+faddress+'): ' + e.message,logpath);         imconnected:=false;         try           tcpcli.disconnect;         except on e:exception         end;         posttolog('imconnected=false',logpath);       end;     end;       flock.leave;   end; end;  procedure tclientthread.execute; begin   createsocket;    while not terminated   begin     getimagestreamtcp;     sleep(200);   end;   try     tcpcli.disconnect;   except on e:exception   end;   freeandnil(tcpcli);    posttolog(faddress+' terminated.',logpath); end; 

the problem service hangs without errors. think problem in criticalsection, because if fill code enough logging last logs entries before flock.enter.

could tell me i'm doing wrong?

i'm sorry if created duplicate of question. tried find same questions, no results.

you should use construction this

type   tdevice = class   protected     fcriticalsection: tcriticalsection;     fdevname: string;     fms: tmemorystream;   public     constructor create;     destructor destroy; override;     procedure lock;     procedure unlock;      property devname: string read fdevname write fdevname;     property ms: tmemorystream read fms write fms;   end;  ...  constructor tdevice.create; begin   inherited create;   fcriticalsection := tcriticalsection.create;   fms:=tmemorystream.create; end;  destructor tdevice.destroy; begin   freeandnil(fcriticalsection);   freeandnil(fms);   inherited destroy; end;  procedure tdevice.lock; begin   fcriticalsection.enter; end;  procedure tdevice.unlock; begin   fcriticalsection.leave; end; 

usage

  device.lock;   try     device.ms... // access       device.unlock;   end; 

and pass whole device anywhere want, not stream.

then can simplify thread

constructor tclientthread.create(const address:string;   adevice:tdevice); begin   inherited create(false); 

and handle exception in execute

procedure tclientthread.execute; begin   try     ... code here ...   except    end; end; 

Comments