我用多线程和下位机通信,收数据的同时写硬盘,但是会出问题。
各位大哥看看我的代码出了什么问题,为什么总是异常
主线程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],可是用了信号量应该不会出现冲突的事情啊。
各位大哥看看我的代码出了什么问题,为什么总是异常
主线程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],可是用了信号量应该不会出现冲突的事情啊。
好像你的WaitForSingleObject不是地方,应该在县城外等待线程结束,而不是在线程内部吧
如果是在主线程创建的, 如果第2个设为true,在启动线程前要,要先ReleaseMutex , 为false则不要,表示创建所在线程不拥有控制权
在线程函数内, WaitForSingleObject ReleaseMutex 成对使用就行
里边的全局变量需要做同步,要不使用局部变量来替换, 看你的代码都没必要使用全局变量另外
Buf1:array [0..8388608] of Byte;
datasize: Integer;
f10:file of Byte;
filename1:string;
这些应该都封装到你的线程类里去,而不是做一个全局的