首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

这个多线程如何不同步执行

2012-02-28 
这个多线程怎么不同步执行?我在D6+Winxp SP2下编写了以下程序,请问两个Edit的内容怎么不同步更新呢?unit t

这个多线程怎么不同步执行?
我在D6+Winxp SP2下编写了以下程序,请问两个Edit的内容怎么不同步更新呢?
unit test1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
  Edit1: TEdit;
  Edit2: TEdit;
  Label1: TLabel;
  Label2: TLabel;
  TrackBar1: TTrackBar;
  TrackBar2: TTrackBar;
  Label3: TLabel;
  Label4: TLabel;
  Button1: TButton;
  Button2: TButton;
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  private
  { Private declarations }
  public
  { Public declarations }
  end;

  TMyThread=class(tthread)
  Fm,Fn:integer;
  FEdit:TEdit;
  procedure Show;
  constructor create(m,n:Integer;myEdit:TEdit);
  procedure execute;override;
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.create(m, n: Integer; myEdit: TEdit);
begin
  inherited create(false);
  Fm:=m;
  Fn:=n;
  FEdit:=myEdit;
  freeonterminate:=true; // 线程终止时自动删除对象,
end;

procedure TMyThread.execute;
begin
  synchronize(show); // 线程调用同步
end;

procedure TMyThread.Show;
var
  i:Integer;
begin
  for i:=Fm to Fn do
  begin
  FEdit.Text:='循环到:'+IntToStr(i);
  FEdit.Update;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  T1,T2:TmyThread;
begin
  Edit1.Text:='';
  Edit2.Text:='';
  T1:=TMyThread.create(1,20000,Edit1);
  T2:=TMyThread.create(20001,50000,Edit2);
end;

end.  


[解决办法]
把循环放在execute中,而不是Show中:

type
TMyThread=class(tthread) 
Fm,Fn: Integer; 
FEdit: TEdit; 
i : Integer;
procedure Show; 
constructor create(m,n:Integer;myEdit:TEdit); 
procedure execute;override; 
end; 

procedure TMyThread.execute; 
begin 
for i := Fm to Fn do 
synchronize(show);
end; 

procedure TMyThread.Show; 
begin 
FEdit.Text:= '循环到: ' + IntToStr(i); 
FEdit.Update; 
end; 

[解决办法]
我所说的和 seamansoft 就是不一样的哇。 你没明白synchronize的原理,所以才会有这样的疑问。

在execute中代码是按线程的方式运作的,也就是说它们是并行工作的。用synchronize调用的代码是在主线程中以消息机制、按串行方式工作的。你把循环放在synchronize中去执行的话,一个循环结束之前,另一个循环是不会开始的。

当然,我上面给出的代码也有些问题,就是循环变量得是局部变量。修改如下:

type
TMyThread=class(tthread)
Fm,Fn:integer;
FEdit:TEdit;
Fi : Integer;
procedure Show;
constructor create(m,n:Integer;myEdit:TEdit);
procedure execute;override;
end;


procedure TMyThread.execute;
var
i : Integer;
begin
for i := Fm to Fn do
begin
Fi := i;
synchronize(show);
end;
end;

procedure TMyThread.Show;
begin
FEdit.Text:= 循环到:'+IntToStr(Fi);
FEdit.Update;
end;

你试一下就知道这样的代码是不是符合你的要求了。
[解决办法]
多线程使用的必要性当中的什么等待慢速设备之类的,我就不多提了,各式各样的资料当中都有说明。
比如楼上的问题当中,实际上很显而易见的就是把一个大的循环作业分成多个线程去做。通常情况下我们说,一个循环,只要前一步运算结果与后一步的运算结果互不影响(不是没有联系)就可以把它分成多个任务,从而让多个人,在这里可以假定为多台电脑(如果运算强度比较大的话,这也是可行的)去完成。在同一台机器上面,则我们说得比较多的就是多进程和多线程,而对于进程来讲,分配的资源会比较多,并且启动和销毁,数据同步等开销相当大,所以在能使用多线程的情况下尽可能采用多线程。但是线程也并不是越多越好,否则的话,多个线程共享同一个CPU,那么指令在CPU当中同样是串行的,而这个线程的切换是有相当开销的,反倒有可能引起性能下降。而推荐的情况就是当没有低速设备参与的情况下,一般地就是根据CPU的并行能力,通俗一点,就目前来讲,那就是逻辑核个数。这样子才能达到真正并行处理的目的。

热点排行