我用多线程和下位机通信,收数据的同时写硬盘,但是会出问题。
各位大哥看看我的代码出了什么问题,为什么总是异常
主线程procedure TtestparaFrm.SS1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Buf,Buf1,Buf2,filename30:String;
  i,BufLen,TemporaryVar:Integer;
begin
  Buf:=Socket.ReceiveText; //Socket收到的字符串放入BUF中
  Buflen:=Length(Buf);  for i:=1 to Buflen do  //将数据放入File_recv_buf中,File_recv_buf是全局数组
    begin
      File_recv_buf[i+perbaglength-1]:=ord(Buf[i]); //perbaglength用于记录收到数据的大小
    end;
  perbaglength:=Buflen+perbaglength;  if  (perbaglength >= 8192*1024) then  //当perbaglength累积到8M的时候,创建线程Filesave1用于写文件
    begin
       for i:=0 to   perbaglength-1 do
       begin
          File_recv_buf2[i]:=File_recv_buf[i];//File_recv_buf2也是全局数组
       end;
     //File_recv_buf2中是要写入文件的数据,perbaglength是大小,filename是文件名
       Filesave1:=TFileThread.Create(File_recv_buf2,perbaglength,filename); 
       perbaglength:=0;  //将记录清零,循环。
    end;end;分线程unit FileThread;interfaceuses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,Dialogs;type
  TFileThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  public
    Constructor Create(var Buf:array of Byte;PerData:Integer;filenamecc:string);
  end;
implementation
Uses testpara,PublicFunction;var
    Buf1:array [0..8388608] of Byte;
    datasize: Integer;
    f10:file of Byte;
    filename1:string;
{Buf:存储要写入文件的数据
 PerData:数据长度
 filename:文件名
 }
Constructor TFileThread.Create (var Buf:array of Byte;PerData:Integer;filenamecc:string);
var
 i:Integer;
begin
  for i:=0 to  PerData-1 do
  begin
  Buf1[i] :=Buf[i];
  end;
  datasize:=PerData;
  filename1:=filenamecc;
  Inherited Create (False);
end;procedure TFileThread.Execute;
var
  i,j:Integer;
  filename2:string;
  size:LongInt;
begin
   FreeOnTerminate:=True;
   if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then//信号量hMutex,防止多线程同时访问相同数据
   begin
     try
       filename2:=filename1;
       system.Assign(f10,filename2);
       system.Reset(f10);
       size:=filesize(f10);
       system.Seek(f10,size);
       system.BlockWrite(f10,Buf1,datasize);
       system.Close(f10);
     finally
      ReleaseMutex(hMutex);
     end;
   end;
end;end.如果在主线程的赋值语句File_recv_buf2[i]:=File_recv_buf[i];中,将File_recv_buf[i]换成一个常数,则程序不会出现问题,而且写入文件的数据量和下位机发的大小完全相等。我觉得可能是两个线程同时访问了File_recv_buf2[i],可是用了信号量应该不会出现冲突的事情啊。

解决方案 »

  1.   

    线程不同步,同时访问一个全局数组导致,加上互斥吧
    好像你的WaitForSingleObject不是地方,应该在县城外等待线程结束,而不是在线程内部吧
      

  2.   

    WaitForSingleObject 没错的, 把你的创建代码帖出来 CreateMutex代码,
    如果是在主线程创建的, 如果第2个设为true,在启动线程前要,要先ReleaseMutex , 为false则不要,表示创建所在线程不拥有控制权
    在线程函数内, WaitForSingleObject ReleaseMutex 成对使用就行
      

  3.   

    SS1ClientRead 应该是放在线程执行的
    里边的全局变量需要做同步,要不使用局部变量来替换, 看你的代码都没必要使用全局变量另外
      Buf1:array [0..8388608] of Byte;
      datasize: Integer;
      f10:file of Byte;
      filename1:string;
    这些应该都封装到你的线程类里去,而不是做一个全局的