R
Richard3000
Unregistered / Unconfirmed
GUEST, unregistred user!
[red]来自:Richard3000, 时间:2003-3-10 14:51:00, ID:1668867 | 编辑
我查到为什么了。
一个共用变量,一个线程,一个procedure。thread和procedure都要访问变量,procedure写
thread读。好象是thread一直占有变量,procedure得不到它,写的时候就出错了。
我想把procedure也写成thread,可是我不知道怎么控制变量的读写。用信号量,还是互斥,
还是临界区?[/red]
[blue]来自:Richard3000, 时间:2003-3-10 12:12:00, ID:1668421 | 编辑
很奇怪!
我现在改用TObjectQueue,但是在Push的时候老是出错!为什么?
Balance:=TBalance.Create;
with Balancedo
begin
WriteTime:=Now;
BalanID:=BalanID;
SerialID:=Copy(IntToStr(GetTickCount()),1,5);
Weight:=Random(300);
end;
BalanceList.BalanceQueue.Push(Balance);
//压入链表当中BalanceQueue为TObjectQueue[/blue]
目前的问题:
一台PC要用令牌的方式访问几十台电子秤。从电子秤读来的数据要保存到资料库中。因为从电子秤读数据非常快,要先存在RAM中再向Database中写。
我的想法是定义一个链表,用于保存从电子秤读来的数据。
然后用线程的Execute,把数据保存到数据库当中。
现定义数据结构如下:
unit UntBalance;
interface
uses
Windows,Classes,ADODB;
type
PBalance=^TBalanceNode;
TBalance=record
BalanID:String[2];//秤号:2位ASCII码
SerialID:String;//流水号:5位ASCII码
Weightouble;//重量
WriteTimeouble;//最后一次访问时间
isBusy:Boolean;
end;
TBalanceNode=record //定义一个双向链表以记录从电子秤读来的数据
Balance:TBalance;
//数据
PreviousBalance;
//前一个
NextBalance;
//后一个
end;
TBalanceNodeList = class(TThread)
private
ADOQuery:TADOQuery;
FHead, FTail: PBalance;
protected
procedure Execute;override;
public
constructor Create(aADOQuery:TADOQuery);
destructor Destroy;
override;
procedure Empty;
procedure Pop;
function First: TBalance;
function isEmpty:Boolean;
procedure Push(aBalance:TBalance);
end;
var
BalanceList:TBalanceNodeList;
implementation
constructor TBalanceNodeList.Create(aADOQuery:TADOQuery);
begin
FHead:=nil;
FTail:=nil;
ADOQuery:=aADOQuery;
inherited Create(false);
end;
destructor TBalanceNodeList.Destroy;
begin
Empty;
inherited;
end;
procedure TBalanceNodeList.Execute;
var
Balance:TBalance;
begin
if not Assigned(ADOQuery) then
Exit;
while Truedo
begin
if not BalanceList.isEmpty then
Balance:=BalanceList.First
else
begin
Sleep(2000);
//链表为空,休息2秒
Continue;
end;
try
with ADOQuerydo
begin
if Active then
Close;
SQL.Clear;
SQL.Add('INSERT INTO SaveData (BalanceID,Serial,WriteTime)');
SQL.Add(' VALUES BalanceID,:Serial,:WriteTime)');
Parameters.ParamByName('BalanceID').Value:=Balance.BalanID;
Parameters.ParamByName('Serial').Value:=Balance.SerialID;
Parameters.ParamByName('WriteTime').Value:=Balance.WriteTime;
ExecSQL;
end;
BalanceList.Pop;
//保存成功。链表的第一个无素抛出来,放弃
except
Continue;
end;
end;
end;
procedure TBalanceNodeList.Empty;
var
tempBalanceBalance;
begin
tempBalance:=fHead;
while Assigned(tempBalance)do
begin
FHead:=FHead^.Next;
Dispose(tempBalance);
tempBalance:=fHead;
end;
end;
procedure TBalanceNodeList.Push(aBalance:TBalance);
var
tempBalanceBalance;
begin
tempBalance:=FTail;
if Assigned(FTail) then
//链表不空
begin
New(FTail^.Next);
tempBalance^.Next:=FTail;
FTail^.Previous:=tempBalance;
end else
begin
New(FHead);
New(FTail);
FHead^.Next:=FTail;
FTail^.Previous:=FHead;
end;
FTail^.Balance:=aBalance;
end;
function TBalanceNodeList.isEmpty;
begin
Result:=(FHead=nil) or (FHead^.Next=nil) or (FHead=FTail);
end;
procedure TBalanceNodeList.Pop;
var
pTempBalance;
begin
if isEmpty then
Exit;
pTemp:=FHead^.Next;
FHead^.Next:=pTemp^.Next;
Dispose(pTemp);
end;
function TBalanceNodeList.First:TBalance;
begin
Result:=FHead^.Balance;
end;
end.
但是在POP时经常出错。
不知道为什么?
请各位仁兄帮我!
我查到为什么了。
一个共用变量,一个线程,一个procedure。thread和procedure都要访问变量,procedure写
thread读。好象是thread一直占有变量,procedure得不到它,写的时候就出错了。
我想把procedure也写成thread,可是我不知道怎么控制变量的读写。用信号量,还是互斥,
还是临界区?[/red]
[blue]来自:Richard3000, 时间:2003-3-10 12:12:00, ID:1668421 | 编辑
很奇怪!
我现在改用TObjectQueue,但是在Push的时候老是出错!为什么?
Balance:=TBalance.Create;
with Balancedo
begin
WriteTime:=Now;
BalanID:=BalanID;
SerialID:=Copy(IntToStr(GetTickCount()),1,5);
Weight:=Random(300);
end;
BalanceList.BalanceQueue.Push(Balance);
//压入链表当中BalanceQueue为TObjectQueue[/blue]
目前的问题:
一台PC要用令牌的方式访问几十台电子秤。从电子秤读来的数据要保存到资料库中。因为从电子秤读数据非常快,要先存在RAM中再向Database中写。
我的想法是定义一个链表,用于保存从电子秤读来的数据。
然后用线程的Execute,把数据保存到数据库当中。
现定义数据结构如下:
unit UntBalance;
interface
uses
Windows,Classes,ADODB;
type
PBalance=^TBalanceNode;
TBalance=record
BalanID:String[2];//秤号:2位ASCII码
SerialID:String;//流水号:5位ASCII码
Weightouble;//重量
WriteTimeouble;//最后一次访问时间
isBusy:Boolean;
end;
TBalanceNode=record //定义一个双向链表以记录从电子秤读来的数据
Balance:TBalance;
//数据
PreviousBalance;
//前一个
NextBalance;
//后一个
end;
TBalanceNodeList = class(TThread)
private
ADOQuery:TADOQuery;
FHead, FTail: PBalance;
protected
procedure Execute;override;
public
constructor Create(aADOQuery:TADOQuery);
destructor Destroy;
override;
procedure Empty;
procedure Pop;
function First: TBalance;
function isEmpty:Boolean;
procedure Push(aBalance:TBalance);
end;
var
BalanceList:TBalanceNodeList;
implementation
constructor TBalanceNodeList.Create(aADOQuery:TADOQuery);
begin
FHead:=nil;
FTail:=nil;
ADOQuery:=aADOQuery;
inherited Create(false);
end;
destructor TBalanceNodeList.Destroy;
begin
Empty;
inherited;
end;
procedure TBalanceNodeList.Execute;
var
Balance:TBalance;
begin
if not Assigned(ADOQuery) then
Exit;
while Truedo
begin
if not BalanceList.isEmpty then
Balance:=BalanceList.First
else
begin
Sleep(2000);
//链表为空,休息2秒
Continue;
end;
try
with ADOQuerydo
begin
if Active then
Close;
SQL.Clear;
SQL.Add('INSERT INTO SaveData (BalanceID,Serial,WriteTime)');
SQL.Add(' VALUES BalanceID,:Serial,:WriteTime)');
Parameters.ParamByName('BalanceID').Value:=Balance.BalanID;
Parameters.ParamByName('Serial').Value:=Balance.SerialID;
Parameters.ParamByName('WriteTime').Value:=Balance.WriteTime;
ExecSQL;
end;
BalanceList.Pop;
//保存成功。链表的第一个无素抛出来,放弃
except
Continue;
end;
end;
end;
procedure TBalanceNodeList.Empty;
var
tempBalanceBalance;
begin
tempBalance:=fHead;
while Assigned(tempBalance)do
begin
FHead:=FHead^.Next;
Dispose(tempBalance);
tempBalance:=fHead;
end;
end;
procedure TBalanceNodeList.Push(aBalance:TBalance);
var
tempBalanceBalance;
begin
tempBalance:=FTail;
if Assigned(FTail) then
//链表不空
begin
New(FTail^.Next);
tempBalance^.Next:=FTail;
FTail^.Previous:=tempBalance;
end else
begin
New(FHead);
New(FTail);
FHead^.Next:=FTail;
FTail^.Previous:=FHead;
end;
FTail^.Balance:=aBalance;
end;
function TBalanceNodeList.isEmpty;
begin
Result:=(FHead=nil) or (FHead^.Next=nil) or (FHead=FTail);
end;
procedure TBalanceNodeList.Pop;
var
pTempBalance;
begin
if isEmpty then
Exit;
pTemp:=FHead^.Next;
FHead^.Next:=pTemp^.Next;
Dispose(pTemp);
end;
function TBalanceNodeList.First:TBalance;
begin
Result:=FHead^.Balance;
end;
end.
但是在POP时经常出错。
不知道为什么?
请各位仁兄帮我!