请教通讯 多线程访问 全局变量 Tlist的问题
function OnGetPortData(var Buf; var BufLen: Integer): Integer;
QueryResultList: TList; 全局变量
函数是接受到数据进行处理 是多线程的 也就是可能同时存在多个线程调用该函数
TOpQImageResult = record
OpTagNo: Integer;
RequestListNo: array[0..20] of Char; 请求的序列号
RequestResult : array[0..20] of Char; 请求的结果放在里面
end;
POpQImageResult = ^TOpQImageResult;
所用到的结构体
function OnGetPortData(var Buf; var BufLen: Integer): Integer;
var
QueryListNo :string;
pResult: POpQImageResult;
begin
QueryListNo:=Copy(FormatDateTime('YYMMDDHHMMSSZZZ', Now), 1, 14);
New(pResult);
pResult^.OpTagNo := 0;
StrPCopy(pResult^.RequestListNo, QueryListNo);
EnterCriticalSection(g_RCSResult);
QueryResultList.Add(pResult);
LeaveCriticalSection(g_RCSResult);
dt := Now;
while ((Now-dt)*24*3600)<30000do //大于30秒认为是超时
begin
if pResult =nil then
Break;
if pResult^.OpTagNo=1 then // 判断是否有结果返回
begin
IsOK := True;
Break;
end;
Sleep(50);
end;
if IsOK then
begin
把结果返回
end;
end;
另外建一个单线程 处理请求
procedure Tthread1.Execute;
var
p: POpQImageResult;
begin
EnterCriticalSection(g_RCSResult);
try
if QueryResultList.Count>0 then
begin
j:=0;
for i:=0 to QueryResultList.Count-1 do
begin
if Terminated then
exit;
pImageResult:= QueryResultList.Items[i-j];
if pImageResult <> nil then
if (pImageResult.OpTagNo=1)then
begin
QueryResultList.Delete(i-j);
inc(j);
dispose(pImageResult);
pImageResult :=nil;
InterlockedDecrement(ImgNum);
end;
end;
end;
finally
LeaveCriticalSection(g_RCSResult);
end;
// 以上这段是处理 将全局变量QueryResultList 中OpTagNo标志为1的删掉
for i:=0 to QueryResultList.Count-1 do
begin
p := QueryResultList.Items[i];
if (p=nil) then Continue;
if (p<>nil) and (p^.OpTagNo=0) then
begin
//根据p^.RequestListNo查询数据库 得到结果复制给p^.RequestResult
然后,执行
p^.OpTagNo=1;改写标志位
end;
end;
end;
这个服务程序运行一段时间 就会非法地址访问 服务死掉 好郁闷啊 。。。。。。。。。
个人觉得是全局变量QueryResultList 没有控制好 但又不知道 什么地方的问题 请各位老大 帮帮忙看看 先谢了
[解决办法]
你改成这们的试试,一般像这种从0到count的会出现这种错误 ~~~!
if QueryResultList.Count>0 then begin for i:=QueryResultList.Count-1 downto 0 do begin if Terminated then exit; pImageResult:= QueryResultList.Items[i]; if pImageResult <> nil then if (pImageResult.OpTagNo=1)then begin QueryResultList.Delete(i); dispose(pImageResult); pImageResult :=nil; InterlockedDecrement(ImgNum); end; end; end;
[解决办法]
使用TThreadList替代TList
访问时使用
var list: TList;begin list := ThreadList.LockList; try //这里访问List finally THreadList.UnlockList; end; ...end;