各位走过路过的高手帮帮忙喽~~~~~~嘿嘿!!
小弟在做串口接收数据的时候用的是多线程,其中主体的Excute中只有几句代码
while not Terminated do
begin
  Synchronize(ReadPort);
end;
现在的问题是,我开了三个线程用来接收串口一、二、三上来的数据,在一个线程接收的时候我将其余的两个线程挂起(线程名.Suspend),在不断的挂起(Suspend),恢复(Resume)过程中,会出现程序死在那里的现象(本来接收线程开的时候CPU占用率达到80%以上,但是这时CPU占用率不超过5%)。这三个线程都是同一个类的不同对象。我就想问问各位高手,怎么样能避免程序死在那里?是不是由于Synchronize函数才会出现这种情况的啊?先谢谢大家了!!分不够再加~~~~

解决方案 »

  1.   

    定义全局变量
    CRITICAL_SECTION g_cs;  //临界区__fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
            InitializeCriticalSection(&g_cs);  //初始化临界区
        .....

    在读数据或写数据前
    EnterCriticalSection(&g_cs);//进入临界区
    ....
    LeaveCriticalSection(&g_cs);//退出临界区记得关闭程序前
    DeleteCriticalSection(&g_cs);
      

  2.   

    如果你的ReadPort中也有线程的话,可能会出现这种情况
    可以试试楼上的
      

  3.   

    通过Synchronize(ReadPort)控制同步不需要手工实现挂起(线程名.Suspend)吧,应该是系统自动将线程排队。
      

  4.   

    >>我开了三个线程用来接收串口一、二、三上来的数据
    这种情况,应该不用挂起线程,也不用 Synchronize
      

  5.   

    [小弟在做串口接收数据的时候用的是多线程,其中主体的Excute中只有几句代码
    while not Terminated do
    begin
      Synchronize(ReadPort);
    end;]多线程的程序这么写那多线程还有意义么?
      

  6.   

    var
        _flag1:integer=0;
        _flag2:integer=0;
        BaseTime:TDatetime;
        
    procedure TReadThread.Execute;
    begin
      { Place thread code here }
        _Pos:=0;
        while not Terminated do
        begin
          Synchronize(ReadPort);
        end;
    end;function TReadThread.TimeInterval(Time_S,Time_E:TDatetime):integer;
    var
        Hour_S,Minute_S,Second_S,MSec_S:Word;
        Hour_E,Minute_E,Second_E,MSec_E:Word;
    begin
        if Time_S<=Time_E then
        begin
          decodetime(Time_S,Hour_S,Minute_S,Second_S,MSec_S);
          decodetime(Time_E,Hour_E,Minute_E,Second_E,MSec_E);
          Result:=(Hour_E-Hour_S)*3600000+(Minute_E-Minute_S)*60000+(Second_E-Second_S)*1000+(MSec_E-MSec_S)
        end
        else
        begin
          decodetime(Time_E,Hour_S,Minute_S,Second_S,MSec_S);
          decodetime(Time_S,Hour_E,Minute_E,Second_E,MSec_E);
          Result:=((Hour_E-Hour_S)*3600000+(Minute_E-Minute_S)*60000+(Second_E-Second_S)*1000+(MSec_E-MSec_S))*(-1);
        end;
    end;procedure TReadThread.ReadPort;
    var
        inbuff:array [0..255] of char;
        hcomm:Thandle;
        nByteRead,dwError:longword;
        cs:TComStat;
        i:integer;
        RecvStr:string;
    begin
        hcomm:=SeriesPort;
        if (hcomm=0) then Exit;
        ClearCommError(hcomm,dwError,@cs);
        ReadFile(hcomm,inbuff,cs.cbInQue,nByteRead,nil);
        //接收通信端口的数据
        if cs.cbInQue=0 then
        begin
          if _flag1=1 then//   表示上次监听端口时串口有数据
          begin
            _flag1:=0;
            _flag2:=1;
            BaseTime:=now;//设置时间基数
          end
          else //此时_flag1为0 表示上次监听端口时串口无数据
          begin
            if _flag2=1 then
            begin
              if TimeInterval(BaseTime,now)>20 then//比较当前时间与时间基数的差值
              begin
                _flag2:=0;
                //字符串结束时(即一帧接收完毕时)的动作
                DataHandle(SerisePortID);//接收字符的处理函数
              end;
            end
            else Exit;
          end;
          Exit;
        end;
        //串行在读取数据后,会自动将缓冲区中已被读取的数据清除掉
        //if cs.cbInQue=0 then exit;
        //数据是否大于所准备的buffer
        if cs.cbInQue>sizeof(inbuff) then
        begin
          PurgeComm(hcomm,PURGE_RXCLEAR);//清除通信端口数据
          exit;
        end;
        _flag1:=1;//表明收到数据了    RecvStr:='';
        for i:=0 to cs.cbInQue-1 do //取出数据
        begin
          ReceByte[i+_Pos]:=ord(inbuff[i]);
          RecvStr:=RecvStr+inttohex(ReceByte[i+_Pos],2)+' ';
        end;
        RunLog('R:'+RecvStr);
        _Pos:=_Pos+integer(cs.cbInQue);
        //如果串口中有数据的话,就将数据读出并添加到ReceByte字节数组中
        //_Pos代表了接收到的字符的个数
    end;各位大侠,上面就是我串口接收线程的代码部分,之所以不断的挂起恢复线程,是因为如果三个线程一起开的话,内存的占用量相当的大,整个界面的相应就会变得很慢。看了各位的留言,我想可能是我的思路有些问题,大家有什么好的方式来解决这个问题吗?谢谢各位了~~~:)