在txt文件中记录线程运行信息报I/O错误(24分)

  • 主题发起人 主题发起人 月满C楼
  • 开始时间 开始时间

月满C楼

Unregistered / Unconfirmed
GUEST, unregistred user!
//线程Execute过程中报I/O错误
//Unit Define 中定义全局变量
unit Define;

interface
uses SysUtils;
var
glo_x,glo_y:integer;
mReWsyn:TMultiReadExclusiveWriteSynchronizer;
F:TextFile;
fPath:string;
implementation
end.

//Unit Threads
unit Threads;

interface
uses
Classes,Define,SysUtils;

type
TComputeThread = class(TThread)
private
{ Private declarations }
Fterminated: Boolean;
procedure MultiRead(var i,j:integer);
procedure ExclusiveWrite();
protected
procedure Execute;
override;
public
property Terminated:Boolean read Fterminated Write Fterminated;
constructor Create(create_suspended:boolean);
end;

implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);

and UpdateCaption could look like,
procedure TComputeThread.UpdateCaption;
begin

Form1.Caption := 'Updated in a thread';
end;
}
{ TComputeThread }
constructor TComputeThread.Create(create_suspended: boolean);
begin

inherited create(create_suspended);
FreeOnTerminate:=True;
Fterminated:= Terminated;
end;

procedure TComputeThread.ExclusiveWrite;
begin

mReWsyn.begin
Write;
glo_x:=glo_x + 2;
glo_y:=glo_y + 2;
mReWsyn.EndWrite;
end;

procedure TComputeThread.Execute;
var
i,j:integer;
fpath:string;
begin

{ Place thread code here }
if not terminated then

begin

AssignFile(F,fPath);
while i <100do

begin

MultiRead(i,j);//////////////////////////////////////////////////////////////////
append(F);/////////////////////////////////该行报错/////////////////////////////
writeLn(F,inttostr(ThreadId) + ':////i:' + inttostr(i) + '////____****' + inttostr(j) + '****');
ExclusiveWrite;
end;

CloseFile(F);
end;

end;

procedure TComputeThread.MultiRead(var i,j:integer);
begin

mReWsyn.begin
Read;
i:=glo_x;
j:=glo_y;
mReWsyn.EndRead;
end;

end.
 
文本文件不是线程安全的,同时两个线程往里面写的时候当然发生I/O错误了!
好点的做法是建立一个专门负责写日志的代理线程,所有需要写日志的线程把
任务全部交给这个代理线程去写,这样就不会出现I/O错误了。
 
楼上能给个例子吗?
 
楼上说的不错,做一个专门的线程,功能就是负责往文件里面写入信息,然后其他的产生信息的线程都通过一个接口,把信息提交给这个线程,这样就不会造成冲突了.
 
楼上能给个例子吗?
难道是做个socket本机服务器来接收各个要求写日志线程的信息
 
自己解决了
再定义一个类
type TLog=class
private
FLogStr:string;
procedure WriteLog(S:string);
public
property LogContext:string Read GetLog Write SetLog;
end;
--------------------
procedure SetLog(value:string;)
begin
FLogStr:=value;
WriteLog(value);
end;
定义全局的dolog:TLog;
mReW:TmultiReadExclusiveWriteSynchronizer;
在其他所有要写日志的线程execute
TDoTaskThread.Execute()
begin
inherited;
if not terminated then
begin
;//这样就可以实现同步,不会因为多线程操作同一个txt文件而出现I/O错误
mReW.begin
write;
do
log.LogContext:=inttostr(ThreadId) + ':' + datetimetostr(now);
mReW.endwrite;
end;
end;
 
恩,你这个相当于自己实现了一个临界区来隔离多个写操作。
多看看临界区、互斥量、信号量相关的代码,看MSDN:
EnterCriticalSection
WaitForSingleObject
其实多个线程写日志的代码全部放在Synchronize方法里执行就不冲突了,Synchronize是主线程里面执行,这样就有排队机制,不会再冲突了,但子线程需要等待为代价(Suspend)。
 
写一个方法专门写日志
要加锁
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
481
import
I
I
回复
0
查看
717
import
I
I
回复
0
查看
686
import
I
I
回复
0
查看
682
import
I
后退
顶部