我的目标是在一paintbox上根据所得数据画四幅图,当按某键时数据改变,并同时开启
四条线程来计算,当计算完了后就画图显示,我是这么做的,基本功能能实现,但关闭时就出错。代码如下:
/////////线程
unit Thread_ZB;interfaceuses
Classes,Graphics;type
TZBThread = class(TThread)
private
Area : integer;
{ Private declarations }
protected
procedure Execute; override;
procedure Calculat;
public constructor Create(Are : Integer);
end;
implementationuses NewLine;///为调用newlineform.CalculatZB(Area);
{ TZBThread }
constructor TZBThread.Create(Are : Integer);
begin
Area := Are;
FreeOnTerminate := True;
inherited Create(False);
end;procedure TZBThread.Execute;
begin
{ Place thread code here }
Calculat;
end;
{ TZBThread }
procedure TZBThread.Calculat ;
begin
newlineform.CalculatZB(Area);//根据Area值的不同计算相应图的数据
end;
end.
////////////对线程的创建
unit NewLine;
uses
Thread_ZB;
.
.
.
var ZBThread1,ZBThread2,ZBThread3,ZBThread4 : TZBThread;
.
.
.
procedure TNewLineForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
VK_NEXT : begin
{取得新数据代码略}
if ThreadsEnd then
begin
ThreadsEnd := false;//锁住全局变量ThreadsRunning
ThreadsRunning := 4;//线程数
ZBThread1 := TZBThread.Create(1);
ZBThread1.OnTerminate := ThreadDone;
ZBThread2 := TZBThread.Create(2);
ZBThread2.OnTerminate := ThreadDone;
ZBThread3 := TZBThread.Create(3);
ZBThread3.OnTerminate := ThreadDone;
ZBThread4 := TZBThread.Create(4);
ZBThread4.OnTerminate := ThreadDone;
end;
end;end;
///////////
//////
procedure TNewLineForm.ThreadDone(Sender: TObject);
begin
Dec(ThreadsRunning);///当一个线程执行完后,线程数ThreadsRunning减一
if ThreadsRunning = 0 then
begin
ThreadsEnd := true; //打开全局变量ThreadsRunning
paintbox1.Refresh ;///画图显示
end;
end;
四条线程来计算,当计算完了后就画图显示,我是这么做的,基本功能能实现,但关闭时就出错。代码如下:
/////////线程
unit Thread_ZB;interfaceuses
Classes,Graphics;type
TZBThread = class(TThread)
private
Area : integer;
{ Private declarations }
protected
procedure Execute; override;
procedure Calculat;
public constructor Create(Are : Integer);
end;
implementationuses NewLine;///为调用newlineform.CalculatZB(Area);
{ TZBThread }
constructor TZBThread.Create(Are : Integer);
begin
Area := Are;
FreeOnTerminate := True;
inherited Create(False);
end;procedure TZBThread.Execute;
begin
{ Place thread code here }
Calculat;
end;
{ TZBThread }
procedure TZBThread.Calculat ;
begin
newlineform.CalculatZB(Area);//根据Area值的不同计算相应图的数据
end;
end.
////////////对线程的创建
unit NewLine;
uses
Thread_ZB;
.
.
.
var ZBThread1,ZBThread2,ZBThread3,ZBThread4 : TZBThread;
.
.
.
procedure TNewLineForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
VK_NEXT : begin
{取得新数据代码略}
if ThreadsEnd then
begin
ThreadsEnd := false;//锁住全局变量ThreadsRunning
ThreadsRunning := 4;//线程数
ZBThread1 := TZBThread.Create(1);
ZBThread1.OnTerminate := ThreadDone;
ZBThread2 := TZBThread.Create(2);
ZBThread2.OnTerminate := ThreadDone;
ZBThread3 := TZBThread.Create(3);
ZBThread3.OnTerminate := ThreadDone;
ZBThread4 := TZBThread.Create(4);
ZBThread4.OnTerminate := ThreadDone;
end;
end;end;
///////////
//////
procedure TNewLineForm.ThreadDone(Sender: TObject);
begin
Dec(ThreadsRunning);///当一个线程执行完后,线程数ThreadsRunning减一
if ThreadsRunning = 0 then
begin
ThreadsEnd := true; //打开全局变量ThreadsRunning
paintbox1.Refresh ;///画图显示
end;
end;
还有:Runtime error 217 at 004028B0
这种情况一般在按键一段时间不松开后出现较多
if Terminated then exit;
if Terminated then exit;
还是不行
还有如下错误信息:
Exception EAccessviolation in modale tt.exe at 00001DB6
Access Violation address 00401DB6 in modale "tt.exe "
write of address 41100000
而且非法操作的消息框关不完
出现了那个异常可能是因为多线程访问共享资源冲突问题。
我不知道你这个函数怎么写的。
这个函数里面你做了什么,是不是没有同步共享数据?
if Terminated then exit;
还是不行
还有如下错误信息:
Exception EAccessviolation in modale tt.exe at 00001DB6
Access Violation address 00401DB6 in modale "tt.exe "
write of address 41100000
而且非法操作的消息框关不完
这东西只有在线程执行函数中有循环的时候才有必要!
我也认为错误原因就在那里。但我的确找不到具体问题所在
我的newlineform.CalculatZB(Area);函数里只有读取全局数组是共享部分(没有数据写入)
我对ThreadsRunning变量的处理合理吗,会有冲突吗?
我是当ThreadsRunning 为真就建立四个线程,并把ThreadsRunning值为假
当四个线程结束时就把ThreadsRunning值为真,并刷新画布
我这有什么问题吗?
请各位高手帮帮想一下吧?