我想问一个关于线程的大大的小问题:)有分哦!!不多50,少了再加!! (50分)

  • 主题发起人 主题发起人 zjlcc
  • 开始时间 开始时间
Z

zjlcc

Unregistered / Unconfirmed
GUEST, unregistred user!
问题是:运行中途时不时的会出错!另外我只想用WINAPI解决,别跟我说用TThread
unit Unit1;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
function kk(P:pointer):Longint;stdcall;
function kk1(P:pointer):Longint;stdcall;

implementation
{$R *.DFM}
function kk(P:pointer):Longint;stdcall;
var
a:integer;
begin
Form1.label1.caption:='0';
for a:=1 to 100000 do begin
form1.label1.caption:=inttostr(strtoint(form1.label1.caption)+1);
// Application.ProcessMessages;
end;
end;

function kk1(P:pointer):Longint;stdcall;
var
a:integer;
begin
Form1.label2.caption:='0';
for a:=1 to 100000 do begin
form1.label2.caption:=inttostr(strtoint(form1.label2.caption)+1);
//Application.ProcessMessages;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
hthread,a:thandle;
threadID,b:Dword;
s:string;
begin
// hthread:=createthread(nil,18129,@kk, nil,0,threadid);
// a :=createthread(nil,18129,@kk1,nil,0,b);
CloseHandle(createthread(nil,64000,@kk, nil,0,threadid));
CloseHandle(createthread(nil,64000,@kk1,nil,0,b));
end;

end.
 
unit Unit1;

interface

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

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


end;
function kk(P:pointer):Longint;stdcall;
function kk1(P:pointer):Longint;stdcall;

var
Form1: TForm1;
handle1,handle2:THandle;
cs:TCriticalSEction;
implementation
{$R *.DFM}


function kk(P:pointer):Longint;stdcall;
var
a:integer;

begin

for a:=1 to 100000 do begin
cs.Enter
form1.label1.caption:=inttostr(strtoint(form1.label1.caption)+1);
cs.Leave
// Application.ProcessMessages;
end;
result:=0;
end;

function kk1(P:pointer):Longint;stdcall;
var
a:integer;

begin
for a:=1 to 100000 do begin
cs.Enter
form1.label2.caption:=inttostr(strtoint(form1.label2.caption)+1);
cs.Leave
//Application.ProcessMessages;
end;
result:=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var

threadID,b:Dword;
t:array [0..1] of thandle;
s:string;
begin
// hthread:=createthread(nil,18129,@kk, nil,0,threadid);
// a :=createthread(nil,18129,@kk1,nil,0,b);
label1.Caption:='0';
label2.Caption:='0';
cs:=TCriticalsection.Create
t[0]:=createthread(nil,64000,@kk, nil,0,threadid);

t[1]:=createthread(nil,64000,@kk1,nil,0,b);
while (waitformultipleobjects(2,@t,TRUE,0)=WAIT_TIMEOUT) do
application.processmessages
CloseHandle(t[0]);
CloseHandle(t[1]);
cs.free;
end;

end.
 
jr老兄啊:你的解决办法比我的寿命长多了,可是还是会出现问题
是不是form1.label2.caption:=inttostr(strtoint(form1.label2.caption)+1);
太耗资源呀???我是拷贝你的代码过去试的,感觉运行起来慢了许多
另外我用别的电脑环境试过了,还是一样的错!
在D3编译的

PROJECT1 在 0167:00403538 的模块 PROJECT1.EXE 中导致例外 eedfadeH。
Registers:
EAX=00b904d4 CS=0167 EIP=00403538 EFLGS=00000246
EBX=00403538 SS=016f ESP=00ecef04 EBP=00ecff60
ECX=00407950 DS=016f ESI=00ecef5e FS=1bf7
EDX=00403538 ES=016f EDI=00b93f74 GS=0000
Bytes at CS:EIP:
58 c3 8b c0 53 56 89 c3 89 d6 8b 13 85 d2 74 19
Stack dump:
00403538 00b904d4 00403538 00ecef5e 00b93f74 00ecff60 00ecef20 00ecff94 0040262c 00ecff94 00403624 00ecff6c 00ecff94 00000005 00406d4f 00ecff78
 
有两点要提的:
1.用createthread,原则上是不可以使用vcl的。用了是则极不安全的.我在
form1.label2.caption:=inttostr(strtoint(form1.label2.caption)+1);
之代码前后加了cs.enter/leave,只是为了防止两个线程同时抢gdi资源,
但并没有防止和主线程间的矛盾(注意在主线等待中用了application.processmessage).
另外,由于这句指令(即改变caption)
里用了vcl代码,所以,很可能会对VCL内部的造成破坏.

解决办法是在kk1/kk两个线程里不要用vcl代码,直接用api写.可考虑
SendMessage(hwndMain,wm_自定义消息,i,0),然后用主线来进行更新显示.

我在我的机上win2k/delphi5环境里测试没有问题.那只是说明d5中vcl对线程安全方面作得好一点,
但并不表明d3中没有问题.

2.你感觉到慢是因为主线程里processmessages的执行(刷新显示)比不过kk1/kk的执行.你在kk1/kk中每次
都form1.label1.update强行刷新看看。

 
接受答案了.
 
后退
顶部