定义一个线程类如何多次调用?(50分)

  • 主题发起人 主题发起人 李子
  • 开始时间 开始时间

李子

Unregistered / Unconfirmed
GUEST, unregistred user!
我的想法是定义一个线程类getthread,用getthread.creat(true)建立三个(可变化)线程对象,然后向这三个现成传递一些参数,再用getthread.resume唤醒线程,但我发现同时创建两个线程就出错,而一个线程就没有问题,请大家多指教,以下是部分代码。
var
newthread1:getthread1;
newthread2:getthread1;
newthread3:getthread1;
begin
newthread1:=getthread1.create;
newthread1.FreeOnTerminate:=true;
newthread2:=getthread1.create;
newthread2.FreeOnTerminate:=true;
newthread3:=getthread1.create;
newthread3.FreeOnTerminate:=true;
newthread1.getparams(false,'http://www.tphy.com/main.asp',1);
newthread2.getparams(false,'http://www.tphy.com/index.html',2);
newthread3.getparams(false,'http://www.tphy.com/myguest/lyb.htm',3);
newthread1.Resume;
newthread2.Resume;
//《----这里出错
newthread3.Resume;
end;
 
是不是公用区没处理好。把 getthread1 贴出来看看
 
//线程定义单元
unit getthread;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,mainfrm,
StdCtrls,Nmhttp;
type
getthread1 = class(TThread)
private
{ Private declarations }
protected
procedure GiveAnswer;
procedure Execute;
override;
public
procedure getparams(atonce:boolean;myurl:string;outmemo:integer);
constructor create;
end;
var
OwnUrl:string;
memonum:integer;
nmhttp1:Tnmhttp;
implementation
//下载线程执行过程
procedure getthread1.Execute;
begin
nmhttp1:=Tnmhttp.Create(nmhttp1);
nmhttp1.Get(OwnUrl);
//通过synchronize向主线程传递信息
Synchronize(GiveAnswer);
end;

//从主线程接收参数,如URL地址、显示位置等
procedure getthread1.getparams(atonce:boolean;myurl:string;outmemo:integer);
begin
OwnUrl:=myurl;
memonum:=outmemo;
end;

//现成构造函数
constructor getthread1.Create;
begin
inherited Create(true);
end;

//根据参数把html源文件显示在主窗口
procedure getthread1.GiveAnswer;
begin
case memonum of
1:form1.memo1.text:=nmhttp1.body;
2:form1.memo2.text:=nmhttp1.body;
3:form1.memo3.text:=nmhttp1.body;
end;
end;
end.
 
为什么用全局变量, 不也封装到线程里呢?
 
2个方法:
1、
var
OwnUrl:string;

memonum:integer;

nmhttp1:Tnmhttp;
放类getthread1里面去
2、var改成 threadvar:
threadvar
OwnUrl:string;

memonum:integer;

nmhttp1:Tnmhttp;
 
我试过,还是不行,两个线程时常会得到一样的结果
 
问题出在下面这三个变量的使用上
var
OwnUrl:string;
memonum:integer;
nmhttp1:Tnmhttp
你应该把这三个变量放在类里面。由于没有作多线程临界资源安全控制。
把他们设为全局变量的话,有可能在一个线程里,把他们设为某一个值,
另外一个线程又把他设为别的值了。
推荐这样改:
getthread1 = class(TThread)
private
{ Private declarations }
//change here.....
OwnUrl:string;
memonum:integer;
nmhttp1:Tnmhttp;

protected
procedure GiveAnswer;
procedure Execute;
override;
public
procedure getparams(atonce:boolean;myurl:string;outmemo:integer);
constructor create;
end;
 
Does it works?
 
一般来说,如果有多个子线程同时运行,
一般不是由主线程去拿子线程计算出来的值(复杂,也不知道子线程现在是否算好了)
而是由子线程干完了把值告诉主线程(简单)。
 
多人接受答案了。
 

Similar threads

后退
顶部