我之前有请教过一个关于多线程操作文件没有保护,造成程序死掉的问题,后来我去掉了一些共有变量,取消了对 ini 文件的写操作,最后暂时解决了问题.但是现在我必须要对文件的写操作,进行记录,而且后期可能需要加入的相关操作会更多.所以,多线程写文件这个问题急待解决.小弟本身也是新手,只有再次提问.查了一些相关 IdTCPServer 的资料,在代码中使用了 Synchronize 的方法,不过似乎效果不理想,运行起来会出现原来的问题:直接死掉.大概代码如下:
Threadvar
Logip:string;......
//线程处理函数
procedure TForm1.IdTCPServerExecute(AThread: TIdPeerThread);
var
FStream: TFileStream;
FileName,CmdStr,ver,ads,vstr,svr: String;
QEnum: TQEnum;
ini:Tinifile;
begin
CmdStr:=AThread.Connection.ReadLn();
Logip:=PChar(AThread.Connection.Socket.Binding.PeerIP);
if (Length(CmdStr)=0) or (Length(CmdStr)<104) then
begin
Memo1.Lines.Add('非法数据来自 '+Logip);
AThread.Connection.Disconnect;
end;
ver:=Copy(CmdStr,Pos('@',CmdStr)+1,32);
//读取配置文件
ini:=Tinifile.Create(ExtractFilePath(Application.ExeName)+'program.ini');
vstr:=ini.ReadString(ver,'VerString','');
svr:='['+ini.ReadString(ver,'server','')+Logip+']';
FileName:=ini.ReadString(ver,'codefile','');
ads:=ini.ReadString(ver,'ads','Happy gameing|');
ini.Free;
//获取枚举类型
QEnum := TQEnum(GetEnumvalue(TypeInfo(TQEnum),Copy(CmdStr,Pos('<T>',CmdStr)+3,3)));
case QEnum of
MSG:
begin
AThread.Connection.WriteLn(ads);
AThread.Connection.Disconnect;
end;
GET:
begin
if Chkconn(Logip) then
begin
//showmessage('1');
Memo1.Lines.Add(svr +' 插件用户');
//Memo1.Lines.Add(svr);
AThread.Synchronize(Addsvr);
try
FStream := TFileStream.Create(ExtractFilePath(Application.ExeName)+FileName,FmOpenRead);
AThread.Connection.WriteStream(FStream,True,False);
finally
FStream.Free;
AThread.Connection.Disconnect;
end;
end
else
begin
//showmessage('2');
AThread.Synchronize(Delsvr);
if Chkuser(CmdStr,svr,vstr) then
begin
try
FStream := TFileStream.Create(ExtractFilePath(Application.ExeName)+FileName,FmOpenRead);
AThread.Connection.WriteStream(FStream,True,False);
finally
FStream.Free;
AThread.Connection.Disconnect;
end;
end
else
begin
AThread.Connection.Disconnect;
end;
end;
end; //end GET
else
begin
AThread.Connection.WriteLn('Failed');
AThread.Connection.Disconnect;
end;
end;//end case
end;......
//主要的文件操作函数
//增加IP
procedure TForm1.Addsvr;
var
strs:Tstringlist;
begin
strs:=Tstringlist.Create;
strs.LoadFromFile(ExtractFilePath(Application.ExeName)+'server.ini');
if strs.IndexOf(Logip)=-1 then
strs.add(Logip);
strs.SaveToFile(ExtractFilePath(Application.ExeName)+'server.ini');
strs.Free;
end;
//删除IP
procedure TForm1.Delsvr;
var
strs:Tstringlist;
begin
strs:=Tstringlist.Create;
strs.LoadFromFile(ExtractFilePath(Application.ExeName)+'server.ini');
if strs.IndexOf(Logip)<>-1 then
strs.Delete(strs.IndexOf(Logip));
strs.SaveToFile(ExtractFilePath(Application.ExeName)+'server.ini');
strs.Free;
end;
Threadvar
Logip:string;......
//线程处理函数
procedure TForm1.IdTCPServerExecute(AThread: TIdPeerThread);
var
FStream: TFileStream;
FileName,CmdStr,ver,ads,vstr,svr: String;
QEnum: TQEnum;
ini:Tinifile;
begin
CmdStr:=AThread.Connection.ReadLn();
Logip:=PChar(AThread.Connection.Socket.Binding.PeerIP);
if (Length(CmdStr)=0) or (Length(CmdStr)<104) then
begin
Memo1.Lines.Add('非法数据来自 '+Logip);
AThread.Connection.Disconnect;
end;
ver:=Copy(CmdStr,Pos('@',CmdStr)+1,32);
//读取配置文件
ini:=Tinifile.Create(ExtractFilePath(Application.ExeName)+'program.ini');
vstr:=ini.ReadString(ver,'VerString','');
svr:='['+ini.ReadString(ver,'server','')+Logip+']';
FileName:=ini.ReadString(ver,'codefile','');
ads:=ini.ReadString(ver,'ads','Happy gameing|');
ini.Free;
//获取枚举类型
QEnum := TQEnum(GetEnumvalue(TypeInfo(TQEnum),Copy(CmdStr,Pos('<T>',CmdStr)+3,3)));
case QEnum of
MSG:
begin
AThread.Connection.WriteLn(ads);
AThread.Connection.Disconnect;
end;
GET:
begin
if Chkconn(Logip) then
begin
//showmessage('1');
Memo1.Lines.Add(svr +' 插件用户');
//Memo1.Lines.Add(svr);
AThread.Synchronize(Addsvr);
try
FStream := TFileStream.Create(ExtractFilePath(Application.ExeName)+FileName,FmOpenRead);
AThread.Connection.WriteStream(FStream,True,False);
finally
FStream.Free;
AThread.Connection.Disconnect;
end;
end
else
begin
//showmessage('2');
AThread.Synchronize(Delsvr);
if Chkuser(CmdStr,svr,vstr) then
begin
try
FStream := TFileStream.Create(ExtractFilePath(Application.ExeName)+FileName,FmOpenRead);
AThread.Connection.WriteStream(FStream,True,False);
finally
FStream.Free;
AThread.Connection.Disconnect;
end;
end
else
begin
AThread.Connection.Disconnect;
end;
end;
end; //end GET
else
begin
AThread.Connection.WriteLn('Failed');
AThread.Connection.Disconnect;
end;
end;//end case
end;......
//主要的文件操作函数
//增加IP
procedure TForm1.Addsvr;
var
strs:Tstringlist;
begin
strs:=Tstringlist.Create;
strs.LoadFromFile(ExtractFilePath(Application.ExeName)+'server.ini');
if strs.IndexOf(Logip)=-1 then
strs.add(Logip);
strs.SaveToFile(ExtractFilePath(Application.ExeName)+'server.ini');
strs.Free;
end;
//删除IP
procedure TForm1.Delsvr;
var
strs:Tstringlist;
begin
strs:=Tstringlist.Create;
strs.LoadFromFile(ExtractFilePath(Application.ExeName)+'server.ini');
if strs.IndexOf(Logip)<>-1 then
strs.Delete(strs.IndexOf(Logip));
strs.SaveToFile(ExtractFilePath(Application.ExeName)+'server.ini');
strs.Free;
end;
//全局锁
alock:=TCriticalSection.Create;//锁定此行下面的代码,不允许其他线程访问
alock.Acquire;
//Some code
//释放锁定。
alock.Release;
我试试看,呵呵,alock 要定义为全局?应该如何定义?
==============
全局变量,并且需要进行初始化.