线程代码如下:
procedure TAlarmThread.Execute;
var
  tmpr:pAlarmListItem;
begin
  while not terminated do
  begin
    if AlarmLists.AlarmNow.WaitFor(infinite)=wrSignaled then
    begin
      AlarmLists.AlarmNow.ResetEvent;
      AlarmLists.lock.Enter;
      tmpr := AlarmLists.tail;
      while tmpr<>AlarmLists.head do
      begin
        AlarmLists.lock.Leave;
        RA:=tmpr^.data;
        
        if abs(RA.Alevel)<=3 then begin
          if RA.CHID = $ff then
            Synchronize(DealWithCommErr)
          else begin
            NewAlarm := True;
            NewAlarm1 := True;
            Synchronize(AlarmAna);
            ASStr := DMForm.GetAlarmStyle(RA.GateWayID,RA.CCUID,RA.DPUID,RA.CHID);
            LogicAdr := DMForm.GetLogicAdr2(RA.GateWayID,RA.CCUID,RA.DPUID,RA.CHID);            if LogicAdr <>'--' then
            begin
              if MainForm.AlarmEnable(ASStr,abs(RA.Alevel)) then
                if NewAlarm or NewAlarm1 then Synchronize(AddToList);
            end;
          end;
        end;
        
        with AlarmLists do
        begin
          lock.Enter;
          tmpr^.prev^.next := tmpr^.next;
          if tmpr=tail then
            tail := tmpr^.prev
          else
            tmpr^.next^.prev := tmpr^.prev;
          dispose(tmpr);
          dec(NodesNum);
          lock.Leave;
        end;
        AlarmLists.lock.Enter;
        tmpr:=tmpr^.prev;
      end;
      AlarmLists.lock.Leave;
    end;
  end;
end;其中的RA是一个全局的结构变量,AlarmAna和AddToList是两个线程方法,我想问这个线程有问题吗?

解决方案 »

  1.   

      cs : TRTLCriticalSection;
     EnterCriticalSection(cs);
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      //离开临界
      LeaveCriticalSection(cs);用信号量控制
      

  2.   

    cszhz(丑小鸭)是对的,不过需要初始化一些东西,首先必须
    CreateCriticalSection(cs);注意,全局变量都必须使用阻塞或者互技术
      

  3.   

    是不是下面的这些语句都必须在临界区内???
    RA:=tmpr^.data;
            
            if abs(RA.Alevel)<=3 then begin
              if RA.CHID = $ff then
                Synchronize(DealWithCommErr)
              else begin
                NewAlarm := True;
                NewAlarm1 := True;
                Synchronize(AlarmAna);
                ASStr := DMForm.GetAlarmStyle(RA.GateWayID,RA.CCUID,RA.DPUID,RA.CHID);
                LogicAdr := DMForm.GetLogicAdr2(RA.GateWayID,RA.CCUID,RA.DPUID,RA.CHID);            if LogicAdr <>'--' then
                begin
                  if MainForm.AlarmEnable(ASStr,abs(RA.Alevel)) then
                    if NewAlarm or NewAlarm1 then Synchronize(AddToList);
                end;
              end;
            end;
      

  4.   

    不用,在给全局变量赋值前使用Enter……
    赋值之后使用Leav……
      

  5.   

    AddToList这些方法中对其进行访问,要用临界区吗?应该没关系吧
      

  6.   

    没有关系,因为他们本来就是线程安全的,注意:Synchronize,他的作用就是,把那个函数提供给主线程调用,当然是主线程空闲的时候调用。
      

  7.   

    有问题,问题大大的,你看看从头到尾都没有try except finally之类的,而一开始就有
    AlarmLists.lock.Enter的线程阻塞,一次出错,线程永远都进不去了,而这种错误很难调试,建议有良好的编程风格.其他的没有仔细看,太长了,而且很多变量不知道啥玩意.
      

  8.   

    还有问题,你第一个AlarmLists.lock.Enter,有可能没有leave,因为循环可能一次都不执行.。