我开了几个线程同时对数据库进行插入操作,数据同步利用临界资源的方式来实现,
可当程序如果运行了一段时间后(估计半天左右的),程序就处理不过来,而且很耗内存!
把接收到的数据通通给丢掉了,请高手近来帮忙分析下什么原因,有没有好的建议或者解决方法,
小弟在这先谢过了

解决方案 »

  1.   

    那你得先简单说下你线程的Execute里是怎么写的
      

  2.   

    你这么说也太简单了吧
    还是把execute里的代码贴出来
      

  3.   

    unit DealWithR;interfaceuses
      Windows,
      Messages,
      SysUtils,
      Variants,
      Classes,
      Graphics,
      Controls,
      Forms,
      Dialogs,
      ScktComp,
      IniFiles,
      ExtCtrls,
      StdCtrls,
      Funct,
      DB,
      ADODB,
      Activex;type
      DealRtdata1 = class(TThread)
      private
        { Private declarations }
      protected
        procedure Execute; override;
      end;implementation
    uses
      Main, forSql;{ Important: Methods and properties of objects in VCL or CLX can only be used
      in a method called using Synchronize, for example,      Synchronize(UpdateCaption);  and UpdateCaption could look like,    procedure DealRtdata.UpdateCaption;
        begin
          Form1.Caption := 'Updated in a thread';
        end; }{ DealRtdata }procedure DealRtdata1.Execute;
    var
      DateTime: string;
      InfoTime: string;
      Day: string;
      Infostr: string;
      coalid: string;
      FID: string;
      Time: string;
      SensorID: string;
      Status: Integer;
      SenStatus: string;
      Values: Double;
      datebasename: string;
      tmpStr: string;
      i, itmp: Integer;
      aiStatus: array[1..8] of Integer; //状态数组,共8位,每一位对应一个状态
      sqlstr: string;
    begin
      { Place thread code here }  CoInitialize(nil);
      try
        fMain.InfoMemo.Lines.Add('线程一处理开始');
        Infostr := DataInfo; //将全局变量值转换到各现成内部
        DateTime := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
     
        coalid := copy(Infostr, 13, 3);
      
        coalid := inttostr(Ord(coalid[1]) * 256 * 256 + Ord(coalid[2]) * 256 +
          Ord(coalid[3]));
      {取出包中16-22(时间)}
        InfoTime := copy(Infostr, 16, 7);
        InfoTime := fMain.FormatTime(InfoTime);
        Day := FormatDateTime('dd', strtodatetime(InfoTime));
        datebasename := 'TNaturalSensorHistory' + Day;
        tmpStr := copy(Infostr, 27, Length(Infostr) - 4 - 26);
        while tmpStr <> '' do
        begin
          SensorID := copy(tmpStr, 1, 2);
          SensorID := inttostr(Ord(SensorID[1]) * 256 + Ord(SensorID[2]));
          fMain.New.Close;
          fMain.New.SQL.Clear;
          fMain.New.SQL.Add('select FID from  sensor where coalid=''' + coalid +
            ''' and sensorid=''' + SensorID + '''');
          fMain.New.Open;
          if not fmain.New.Eof then
            FID := vartostr(fmain.New.FieldValues['fid'])
          else
          begin
            tmpStr := copy(tmpStr, 7, Length(tmpStr) - 6);
            continue;
          end;
            Values := Ord(tmpStr[3]) * 256 + Ord(tmpStr[4]) + Ord(tmpStr[5]) / 100;
          Status := Ord(tmpStr[6]);
          if Status = 0 then
            SenStatus := '0'
          else
          begin
            for i := 1 to 8 do
            begin        
              itmp := Status shr (i - 1);
              aiStatus[i] := itmp and 1;
            end;
            if aiStatus[1] = 1 then
              SenStatus := '1';
            if aiStatus[2] = 1 then
              SenStatus := '2';
            if aiStatus[3] = 1 then
              SenStatus := '4';
            if aiStatus[4] = 1 then
              SenStatus := '8';
            if aiStatus[5] = 1 then
              SenStatus := '16';
            if aiStatus[6] = 1 then
              SenStatus := '32';
            if aiStatus[7] = 1 then
              SenStatus := '64';
            if aiStatus[8] = 1 then
              SenStatus := '128';
          end;
          try
            if FID <> '' then
            begin
              sqlstr := 'exec date' + day + ' ' + fid + ',' + floattostr(Values) + ',' + SenStatus + ',''' + InfoTime + '''';
              with fMain do
              begin
                try
                  EnterCriticalsection(CS); //--------进入临界区----------
                  adoq.Close;
                  adoq.SQL.Clear;
                  adoq.SQL.Add(sqlstr);
                  adoq.ExecSQL;
                finally
                  LeaveCriticalSection(CS); //---------离开临界区-----------
                end;
              end;
            end
            else
              fMain.WriteToTextFile(GDir + 'NoFresh.txt', '一处理::' + coalid + '的' + SensorID + '没有及时更新!');
          except
            fMain.InfoMemo.Lines.Add(InfoTime + '>>>>>' + SensorID +
              '<<<<<<<''传感器数据存库失败!');
            fMain.WriteToTextFile(GDir + 'Debug.txt', FormatDateTime('yyyy-mm-dd hh:nn:ss', now) +
              '::' + InfoTime + '>>>>>' + SensorID + '<<<<<<<''数据存库失败!');
          end;
          tmpStr := copy(tmpStr, 7, Length(tmpStr) - 6);
        end;
        Month := FormatDateTime('mm', now);
        fMain.InfoMemo.Lines.Add('线程一                                                                     success');
        DealWithRtNum := DealWithRtNum + 1;
        fMain.Edit3.Text := inttostr(DealWithRtNum);
        if Day = '01' then
        begin
          if (IsBak = '0') and (IsBakIng = False) then
          begin
            ForSqlBAndR.Create(False);
          end;
        end;
      finally
        IsThread1ing := False;
        Couninitialize;
        Thread1.Resume;
        fMain.InfoMemo.Lines.Add('线程一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一处理结束');
      end;
    end;end.
      

  4.   

    fMain.New.Open;这里为什么没有同步
    TADOQuery可以每个线程自己动态创建,这样不需要同步
    而且你下面临界区那里那个“CS”是哪里冒出来的