R
rain_2002
Unregistered / Unconfirmed
GUEST, unregistred user!
我在一个系统中,采用了双socket,所以数据量非常的大,而数据包中的内容解析过程相对不较大,所以如果采用一个线程来处理,肯定会丢失很多数据,所以我采用的方式是在数据的录入端采用单链表,数据从链表尾部追加,然后启动多个线程从链表的次接点取数。我一共启动了36个线程来分别获取数据和独立解析,然后送界面显示和数据存储。
可是我封装了一个当链表类,和继承了一个线程类。可是在测试中发现线程在使用一段时间后会死掉。这是怎么回事?
另一方面,由于采用多线程操作,所以每个线程单独占有一的数据库连接,然后都往一个数据表中插入数据,那么会不会出现问题呢(这部分暂时还没加进去测试),各位兄台指点。
我将我的代码列出来,大家帮忙分析一下,看问题出在那,这种思路是否可行??
单链表类:
unit cLinkListu;
interface
uses Classes;
type
PWmisNode = ^TWmisNode;
//单链表中的一个节点
TWmisNode = packed record
nNext : PWmisNode;
nData : string;
end;
TDisposeProc = procedure(aData :string);
type
TWmisLinkList=class(TObject)
private
FHead : PWmisNode;
FSecond : PWmisNode;
FCount : longint;
FCursorIx: Longint;
FDispose: TDisposeProc;
FLast: PWmisNode;
//指向尾节点
public
constructor Create(ADispose:TDisposeProc);
destructor Destroy;
override;
procedure Append(aItem:string);
function DeleteFirst:string;
//获取数据域中的数据
function ShowList:string;virtual;
//输出链表的所有数据域
procedure Clear;
//清除链表中的节点
function Last:string;
property Count :longint read FCount;
property CursorIx:integer read FCursorIx;
end;
var
MyList:TWmisLinkList;
implementation
{初始化链表}
constructor TWmisLinkList.Create(ADispose:TDisposeProc);
begin
inherited create;
FHead:=nil;
new(FHead);
FHead^.nNext:=nil;
//FHead^.nData:='mytest';
FSecond:=nil;
FLast:=nil;
FCount:=0;
FCursorIx:=-1;
FDispose:=ADispose;
end;
{释放链表}
destructor TWmisLinkList.Destroy;
begin
Clear;
//删除除头节点外的所有节点;
Dispose(FHead);
//删除头节点
inherited Destroy;
end;
{删除除头节点外的所有节点}
procedure TWmisLinkList.Clear;
var
TempWmisNode;
begin
Temp:=FHead^.nNext;
while Temp<>nildo
begin
FHead^.nNext:=Temp^.nNext;
if Assigned(FDispose) then
FDispose(Temp^.nData);
Dispose(Temp);
Temp:=FHead^.nNext;
end;
FSecond:=Temp;
FLast:=FSecond;
FCount:=0;
end;
{在链表尾部追加元素}
procedure TWmisLinkList.Append(aItem:string);
var
NewNodeWmisNode;
begin
if FCount>$FFFE then
exit;
new(NewNode);
//首先分配一个节点
NewNode^.nData:=aItem;
NewNode^.nNext:=nil;
if FLast=nil then
begin
FSecond:=NewNode;
FLast:=FSecond;
FHead^.nNext:=FSecond;
end
else
begin
FLast^.nNext:=NewNode;
FLast:=NewNode;
end;
inc(FCount);
//元素数量加1
end;
{返回次节点的数据,并删除次节点}
function TWmisLinkList.DeleteFirst;
//获取数据域中的数据
begin
if FSecond<>nil then
begin
result:=FSecond^.nData;
if Assigned(FDispose) then
FDispose(FSecond^.nData);
FHead^.nNext:=FSecond^.nNext;
Dispose(FSecond);
FSecond:=FHead^.nNext;
dec(FCount);
if FCount=0 then
FLast:=FSecond;
end
else
result:='';
end;
{显示链表中的所有元素}
function TWmisLinkList.ShowList;
//输出链表的所有数据域
var
CurNodeWmisNode;
begin
result:='';
CurNode:=FHead^.nNext;
while CurNode<>nildo
begin
result:=result+CurNode^.nData;
CurNode:=CurNode^.nNext;
inc(FCursorIx);
end;
end;
{返回最后一条记录}
function TWmisLinkList.Last;
begin
if FLast=nil then
begin
result:='';exit;
end;
result:=FLast^.nData;
end;
处理线程类:
type
TParseThread = class(TThread)
private
FLock: TcriticalSection;
FInfo: string;
FInd: integer;
procedure Lock;
procedure Unlock;
procedure FetchLinkList;
procedure DissociateInfoPackage;
protected
procedure Execute;
override;
public
constructor Create(inde:integer);virtual;
destructor Destroy;override;
end;
var
MyParseThread1:TParseThread;
:
:
MyParseThread36:TParseThread;
constructor TParseThread.Create(inde:integer);
begin
inherited Create(false);
FLock := TCriticalSection.Create;
FInfo :='';
end;
destructor TParseThread.Destroy;
begin
FLock.Free;
inherited Destroy;
end;
procedure TParseThread.Execute;
begin
while not Terminateddo
begin
FetchLinkList;
DissociateInfoPackage;
sleep(2);
end;
end;
{加锁}
procedure TParseThread.Lock;
begin
FLock.Enter;
end;
{解锁}
procedure TParseThread.Unlock;
begin
FLock.Leave;
end;
{===================================}
{从链表中获取数据 }
{同步链表的操作 }
{===================================}
procedure TParseThread.FetchLinkList;
begin
Lock;
try
FInfo:=MyList.DeleteFirst;
finally
if FInfo<>'' then
Form1.StatusBar.Panels[3].Text:=inttostr(MyList.Count);
Unlock;
end;
end;
{拆开链表中取出的信息包}
procedure TParseThread.DissociateInfoPackage;
begin
if FInfo<>'' then
begin
lock;
try
//这里放入解析数据相关代码,解析完毕后,送界面显示、
//同时通过从数据库连接池中取出一个连接,来往数据库里面插入数据(多线程同时访问一个表会不会出问题,
//如果不太用这种方式的话,数据库连接池也就没有实际意义了,我的应用中客户端不是很多,请各位兄台指正)
finally finally
Unlock;
end;
sleep(370);
FInfo:='';
end;
end;
敬侯各位dfw高手,各位兄台帮忙阿
可是我封装了一个当链表类,和继承了一个线程类。可是在测试中发现线程在使用一段时间后会死掉。这是怎么回事?
另一方面,由于采用多线程操作,所以每个线程单独占有一的数据库连接,然后都往一个数据表中插入数据,那么会不会出现问题呢(这部分暂时还没加进去测试),各位兄台指点。
我将我的代码列出来,大家帮忙分析一下,看问题出在那,这种思路是否可行??
单链表类:
unit cLinkListu;
interface
uses Classes;
type
PWmisNode = ^TWmisNode;
//单链表中的一个节点
TWmisNode = packed record
nNext : PWmisNode;
nData : string;
end;
TDisposeProc = procedure(aData :string);
type
TWmisLinkList=class(TObject)
private
FHead : PWmisNode;
FSecond : PWmisNode;
FCount : longint;
FCursorIx: Longint;
FDispose: TDisposeProc;
FLast: PWmisNode;
//指向尾节点
public
constructor Create(ADispose:TDisposeProc);
destructor Destroy;
override;
procedure Append(aItem:string);
function DeleteFirst:string;
//获取数据域中的数据
function ShowList:string;virtual;
//输出链表的所有数据域
procedure Clear;
//清除链表中的节点
function Last:string;
property Count :longint read FCount;
property CursorIx:integer read FCursorIx;
end;
var
MyList:TWmisLinkList;
implementation
{初始化链表}
constructor TWmisLinkList.Create(ADispose:TDisposeProc);
begin
inherited create;
FHead:=nil;
new(FHead);
FHead^.nNext:=nil;
//FHead^.nData:='mytest';
FSecond:=nil;
FLast:=nil;
FCount:=0;
FCursorIx:=-1;
FDispose:=ADispose;
end;
{释放链表}
destructor TWmisLinkList.Destroy;
begin
Clear;
//删除除头节点外的所有节点;
Dispose(FHead);
//删除头节点
inherited Destroy;
end;
{删除除头节点外的所有节点}
procedure TWmisLinkList.Clear;
var
TempWmisNode;
begin
Temp:=FHead^.nNext;
while Temp<>nildo
begin
FHead^.nNext:=Temp^.nNext;
if Assigned(FDispose) then
FDispose(Temp^.nData);
Dispose(Temp);
Temp:=FHead^.nNext;
end;
FSecond:=Temp;
FLast:=FSecond;
FCount:=0;
end;
{在链表尾部追加元素}
procedure TWmisLinkList.Append(aItem:string);
var
NewNodeWmisNode;
begin
if FCount>$FFFE then
exit;
new(NewNode);
//首先分配一个节点
NewNode^.nData:=aItem;
NewNode^.nNext:=nil;
if FLast=nil then
begin
FSecond:=NewNode;
FLast:=FSecond;
FHead^.nNext:=FSecond;
end
else
begin
FLast^.nNext:=NewNode;
FLast:=NewNode;
end;
inc(FCount);
//元素数量加1
end;
{返回次节点的数据,并删除次节点}
function TWmisLinkList.DeleteFirst;
//获取数据域中的数据
begin
if FSecond<>nil then
begin
result:=FSecond^.nData;
if Assigned(FDispose) then
FDispose(FSecond^.nData);
FHead^.nNext:=FSecond^.nNext;
Dispose(FSecond);
FSecond:=FHead^.nNext;
dec(FCount);
if FCount=0 then
FLast:=FSecond;
end
else
result:='';
end;
{显示链表中的所有元素}
function TWmisLinkList.ShowList;
//输出链表的所有数据域
var
CurNodeWmisNode;
begin
result:='';
CurNode:=FHead^.nNext;
while CurNode<>nildo
begin
result:=result+CurNode^.nData;
CurNode:=CurNode^.nNext;
inc(FCursorIx);
end;
end;
{返回最后一条记录}
function TWmisLinkList.Last;
begin
if FLast=nil then
begin
result:='';exit;
end;
result:=FLast^.nData;
end;
处理线程类:
type
TParseThread = class(TThread)
private
FLock: TcriticalSection;
FInfo: string;
FInd: integer;
procedure Lock;
procedure Unlock;
procedure FetchLinkList;
procedure DissociateInfoPackage;
protected
procedure Execute;
override;
public
constructor Create(inde:integer);virtual;
destructor Destroy;override;
end;
var
MyParseThread1:TParseThread;
:
:
MyParseThread36:TParseThread;
constructor TParseThread.Create(inde:integer);
begin
inherited Create(false);
FLock := TCriticalSection.Create;
FInfo :='';
end;
destructor TParseThread.Destroy;
begin
FLock.Free;
inherited Destroy;
end;
procedure TParseThread.Execute;
begin
while not Terminateddo
begin
FetchLinkList;
DissociateInfoPackage;
sleep(2);
end;
end;
{加锁}
procedure TParseThread.Lock;
begin
FLock.Enter;
end;
{解锁}
procedure TParseThread.Unlock;
begin
FLock.Leave;
end;
{===================================}
{从链表中获取数据 }
{同步链表的操作 }
{===================================}
procedure TParseThread.FetchLinkList;
begin
Lock;
try
FInfo:=MyList.DeleteFirst;
finally
if FInfo<>'' then
Form1.StatusBar.Panels[3].Text:=inttostr(MyList.Count);
Unlock;
end;
end;
{拆开链表中取出的信息包}
procedure TParseThread.DissociateInfoPackage;
begin
if FInfo<>'' then
begin
lock;
try
//这里放入解析数据相关代码,解析完毕后,送界面显示、
//同时通过从数据库连接池中取出一个连接,来往数据库里面插入数据(多线程同时访问一个表会不会出问题,
//如果不太用这种方式的话,数据库连接池也就没有实际意义了,我的应用中客户端不是很多,请各位兄台指正)
finally finally
Unlock;
end;
sleep(370);
FInfo:='';
end;
end;
敬侯各位dfw高手,各位兄台帮忙阿