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

小弟我的这个多线程为什么会互相影响

2013-12-28 
我的这个多线程为什么会互相影响unit Unit1interfaceusesWindows, Messages, SysUtils, Variants, Classe

我的这个多线程为什么会互相影响

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
  function MyFun(p: Pointer): Integer; stdcall;
var
  i: Integer;
begin
  for i := 0 to 500000 do
  begin
    Form1.Canvas.Lock;
    Form1.Canvas.TextOut(10, 10, IntToStr(i));
    Form1.Canvas.Unlock;
  end;
  Result := 0;
end;


  function MyFun2(p: Pointer): Integer; stdcall;
var
  i: Integer;
begin
  for i := 0 to 500000 do
  begin
    Form1.Canvas.Lock;
    Form1.Canvas.TextOut(60, 60, IntToStr(i));
    Form1.Canvas.Unlock;
  end;
  Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var 
  ID: THandle; 
begin
  CreateThread(nil, 0, @MyFun, nil, 0, ID);
  CreateThread(nil, 2, @MyFun2, nil, 0, ID);

end;

end.


这是我的代码,这两个运算不是同步的,一个快一个慢,而且快的那个算完了,慢的那个也停了,是怎么回事
[解决办法]
使用 api createthread来创建线程,需要把delphi的全局变量 IsMultiThread:=true;

最好的做法是不要使用api,用vcl的BeginThread函数来替代createthread,
BeginThread的参数跟createthread完全一样,其内部已经 IsMultiThread:=true;了

BeginThread(nil, 0, @MyFun, nil, 0, ID);

另外在func1,func2中的 lock 和 unlock 之间加入一句 sleep(0);


 function MyFun(p: Pointer): Integer; stdcall;
var
  i: Integer;
begin
  for i := 0 to 500000 do
  begin
    Form1.Canvas.Lock;
    Form1.Canvas.TextOut(10, 10, IntToStr(i));
    Sleep(0);///////
    Form1.Canvas.Unlock;
  end;
  Result := 0;
end;

function MyFun2(p: Pointer): Integer; stdcall;
var
  i: Integer;
begin
  for i := 0 to 500000 do
  begin
    Form1.Canvas.Lock;
    Form1.Canvas.TextOut(10, 30, IntToStr(i));
    Sleep(0);////////
    Form1.Canvas.Unlock;
  end;
  Result := 0;
end;

[解决办法]
借用sololie的厕所例子:

甲乙两个人,各自算各自的数,算著算著拉起肚子来,
于是要抢厕所。
厕所门是控制一次只能一个人上厕所。

本来你是希望两个人各算各的数,各在需要的时间上厕所,
如此可以体现两个人各自独立的状态。

问题是,他们两个人算的东西太少,上厕所又上得太频繁,
你能想像得到,
最后的结果是,正好一个人上完另一个上。
最后,一个人上完了500000次,另一个人也正好上完了500000次。
感觉好像两个人同步了。

要想不同步就是,算东西的时间不等长。Sleep(1..100)就是来体现这个的。
因为算东西的时间不等长,就有可能一个人上完一次厕所,门口没有人在等,
甚至原先这个人又想上厕所了,另一个人还没上上一次厕所。
如此两个人就不会你方上罢换我上,变成了同步。


[解决办法]
你知道为啥系统崩溃吗?因为你把sleep放到锁之内了,你第一个线程在锁的时候sleep了,第二个线程可以运行了,他去锁canvas结果发现已经被锁了,只能干等着。

热点排行