線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1026
推到 Plurk!
推到 Facebook!

链表与线程(Thread)

尚未結案
Alcohol
一般會員


發表:7
回覆:10
積分:8
註冊:2002-10-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-03-07 12:54:27 IP:211.159.xxx.xxx 未訂閱
目前的问题: 一台PC要用令牌的方式访问几十台电子秤。从电子秤读来的数据要保存到资料库中。因为从电子秤读数据非常快,要先存在RAM中再向Database中写。 现定义数据结构如下: unit UntBalance; interface uses Windows,Classes,ADODB; type PBalance=^TBalanceNode; TBalance=record BalanID:String[2];//秤号:2位ASCII码 SerialID:String;//流水号:5位ASCII码 Weight:Double;//重量 WriteTime:Double;//最后一次访问时间 isBusy:Boolean; end; TBalanceNode=record //定义一个双向链表以记录从电子秤读来的数据 Balance:TBalance; //数据 Previous:PBalance; //前一个 Next:PBalance; //后一个 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 True do begin if not BalanceList.isEmpty then Balance:=BalanceList.First else begin Sleep(2000); //链表为空,休息2秒 Continue; end; try with ADOQuery do 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 tempBalance:PBalance; begin tempBalance:=fHead; while Assigned(tempBalance) do begin FHead:=FHead^.Next; Dispose(tempBalance); tempBalance:=fHead; end; end; procedure TBalanceNodeList.Push(aBalance:TBalance); var tempBalance:PBalance; 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 pTemp:PBalance; 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时经常出错。 不知道为什么? 请各位仁兄帮我! 發表人 - Alcohol 於 2003/03/07 12:56:42
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-03-07 14:29:11 IP:147.8.xxx.xxx 未訂閱
Isn't the Push method being called by the other threads? I think you need to protect your thread's variable. The simplest way (less efficient) is to use a critical section to protect the code accessing the variables. 
系統時間:2024-05-03 12:13:36
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!