多线程出错问题.(附源码) 请教,要怎么改或怎么改比较好.thx (111分)

  • 主题发起人 淡淡的笑
  • 开始时间

淡淡的笑

Unregistered / Unconfirmed
GUEST, unregistred user!
新建项目,在窗口上放一个memo和一个按钮
代码:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Winsock, Grids, ExtCtrls, Menus, ComCtrls;
type
  TForm1 = class(TForm)
    button1: TButton;
    Memo1: TMemo;
    procedure button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TMyThread = class(TThread)
  private
    { Private declarations }
    indexNum:integer;
    procedure AddThread;
    procedure ProgressMy(iNum:integer);
  protected
    procedure Execute;
override;
  public
    constructor Create(iNum:integer);
  end;

var
  Form1: TForm1;
  MaxNum:integer;
  ThreadNum:integer;
implementation
{$R *.DFM}

procedure TForm1.button1Click(Sender: TObject);
var
    PingResult:string;
    MyAddr:string;
    x,y:integer;
    i,j,k:integer;
begin
  ThreadNum:=10;
  MaxNum:=34;
   //  <<<=== 这个设大一点,程序便出错,请问程序要怎么改或怎么改比较好?
  if MaxNum>ThreadNum then
    j:=ThreadNum
  else
    j:=MaxNum;
  for i := 1 to jdo
  begin
    k:=i-1;
    TMyThread.Create(k);
  end;

end;

{ TMyThread }
procedure TMyThread.AddThread;
var
  i:integer;
begin
  //重用线程,结果处理结束后就处理新的任务
  i:=indexNum+ThreadNum;
  if i<=MaxNum then
  begin
    ProgressMy(i);
  end;
end;

constructor TMyThread.Create(iNum: integer);
begin
  indexNum:=iNum;
  inherited Create(False);
end;

procedure TMyThread.Execute;
begin
  //inherited;
  FreeOnTerminate := True;
  ProgressMy(indexNum);
end;

procedure TMyThread.ProgressMy(iNum:integer);
var
  i:integer;
begin
  i:=iNum;
  indexNum:=i;
  form1.memo1.text:=  form1.memo1.text + '|' + inttostr(i);
  AddThread;
end;

end.
 
procedure TMyThread.Execute;
begin
Synchronize(ProgressMy(indexNum));
end;
 
to lilofox:
调用Synchronize()时,过程不能加参数 :O
我把ProgressMy改成调用indexNum后, MaxNum设为1000,程序死掉.
线程数加大也是一样.
 
你最好用Synchronize()方法,把哪个参数设为线程类的一个成员参数,就可以随意使用了
 
AddThread;
这样玩不死才怪。你的线程成了逆归线程,乘乘高手。
改一改吧。
 
to 张无忌:
具体?能否给段代码?
to SSGYK:
线程当中代码不是可以重用的么? 使用的仍是那10个线程,只是把任务重新处理. 能否说清楚点?
ps;
楼上两位大哥. 我领悟力差,,, -_-
 
FLock.Enter;
Try
form1.memo1.text:= form1.memo1.text + '|' + inttostr(i);
finally
fLock.leave;
end;
 
用了临界区还是出错 -_- 我倒...
 
要回家了..明天希望能解决.. 我加分啊 :( 完整的代码哪位兄台给post出来. 谢谢
 
如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Winsock, Grids, ExtCtrls, Menus, ComCtrls;
type
TForm1 = class(TForm)
button1: TButton;
Memo1: TMemo;
procedure button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyThread = class(TThread)
private
{ Private declarations }
indexNum:integer;
// procedure AddThread;
// procedure ProgressMy(iNum:integer);
procedure ProgressMy2;
protected
procedure Execute;
override;
public
constructor Create(iNum:integer);
end;

var
Form1: TForm1;
MaxNum:integer;
ThreadNum:integer;
implementation
{$R *.DFM}

procedure TForm1.button1Click(Sender: TObject);
var
// PingResult:string;
// MyAddr:string;
// x,y:integer;
i,j,k:integer;
begin
ThreadNum:=100;
MaxNum:=20000;
// <<<=== 这个设大一点,程序便出错,请问程序要怎么改或怎么改比较好?
if MaxNum>ThreadNum then
j:=ThreadNum
else
j:=MaxNum;
for i := 1 to jdo
begin
k:=i-1;
TMyThread.Create(k);
end;

end;

{ TMyThread }
{
procedure TMyThread.AddThread;
var
i:integer;
begin
//重用线程,结果处理结束后就处理新的任务
i:=indexNum+ThreadNum;
if i<=MaxNum then
begin
ProgressMy(i);
end;
end;
}
constructor TMyThread.Create(iNum: integer);
begin
indexNum:=iNum;
inherited Create(False);
end;

procedure TMyThread.ProgressMy2;
begin
form1.memo1.Lines.Add('THREAD '+inttostr(indexNum));
end;

procedure TMyThread.Execute;
begin
//inherited;
FreeOnTerminate := True;
while not Terminated and (indexNum<=MaxNum)do
begin
Synchronize(ProgressMy2);
indexNum:=indexNum+ThreadNum;
end;
//ProgressMy(indexNum);
end;
{
procedure TMyThread.ProgressMy(iNum:integer);
var
i:integer;
begin
i:=iNum;
indexNum:=i;
form1.memo1.text:= form1.memo1.text + '|' + inttostr(i);
AddThread;
end;
}
end.
 
谢了,昨天的问题原来是出在 form1.memo1.text:=form1.memo1.text + '|' + inttostr(i);这一句上 -_-
多个线程重复访问 form1.memo1.text的值使得过多的某一线程等待其它线程操作结束。CPU占用100%
为以上各位奉上积分 :) 再次说声谢谢。
 
多人接受答案了。
 
我采用的方法是
procedure TMyThread.Execute;
begin
//inherited;
FreeOnTerminate := True;
Synchronize(MyProcedure);
end;

procedure TMyThread.MyProcedure;
begin
while not Terminated and (indexNum<=MaxNum)do
begin
form1.memo1.Lines.Add('THREAD '+inttostr(indexNum));
indexNum:=indexNum+ThreadNum
end;
end;

比huzzz采用的方法好象比较快一些,不知道会不会出现线程不同步的问题 -_-
 
顶部