读书人

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

发布时间: 2013-12-28 22:19:34 作者: rapoo

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

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结果发现已经被锁了,只能干等着。

读书人网 >.NET

热点推荐