关于多线程的简单问题(200分)

  • 主题发起人 主题发起人 可口白菜
  • 开始时间 开始时间

可口白菜

Unregistered / Unconfirmed
GUEST, unregistred user!
我用多线程但是线程执行时就没法对用户界面进行操作了(无法点击任何控件)
我是这么实现的
type TestThread=Class(TThread)
private
FileName:string;
protected
procedure execute;override;
proceduredo
message;
public
constructor create(suspend:Boolean;FName:string);
type TestThread1=Class(TThread)
private
FileName:string;
protected
procedure execute;override;
proceduredo
message;
public
constructor create(suspend:Boolean;FName:string);
.....

constructor TestThread.Create(Suspend:boolean;FName:string);
begin
inherited Create(Suspend);
FileName:=FName;
ExitOnTerminated:=True;
end;

procedure TestThread.execute;
begin
Synchronize(domessage);
end;

procedure TestThread.domessage;
begin
Form1.Memo1.lines.add(FileName);
end;

constructor TestThread1.Create(Suspend:boolean;FName:string);
begin
inherited Create(Suspend);
FileName:=FName;
ExitOnTerminated:=True;
end;

procedure TestThread1.execute;
begin
Synchronize(domessage);
end;

procedure TestThread1.domessage;
begin
Form1.Memo1.lines.add(FileName);
end;

procedure Form1.button1onclick;
var TestTh:TestThread;
i:integer;
begin
For i:=0 to 255do
begin
TestTh :=TestThread.Create(False,Inttostr(i);
TestTh.Resume;
end;
end;

procedure Form1.button2onclick;
var TestTh:TestThread1;
i:integer;
begin
For i:=0 to 255do
begin
TestTh :=TestThread1.Create(False,Inttostr(i);
TestTh.Resume;
end;
end;
界面上有两个memo,一个edit,两个按钮(button1,button2)
但是我一点击第一个按钮以后,其他的就无法作了,包括第二个按钮的点击和edit 的输入
怎么样才能实现用户界面的操作和这些线程的同步,这些线程能不能只放在后台

而且线程能不能对其对CPU资源占用作限制,因为我做的线程是为了处理图片,单作会
占用99%的CPU资源
谢谢各位大虾了
 
你一次运行256个线程,也太多了。试试这样:
For i:=0 to 255do
begin
TestTh :=TestThread.Create(False,Inttostr(i);
TestTh.Resume;
TestTh..WaitFor;
end;
 
我试了一下, 有点小改动, 你看看吧
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

type
TestThread=Class(TThread)
private
FileName:string;
protected
procedure execute;override;
proceduredo
message;
public
constructor create(suspend:Boolean;FName:string);
end;
type
TestThread1=Class(TThread)
private
FileName:string;
protected
procedure execute;override;
proceduredo
message;
public
constructor create(suspend:Boolean;FName:string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TestThread.Create(Suspend:boolean;FName:string);
begin
inherited Create(Suspend);
FileName:=FName;
FreeOnTerminate:=True;
end;

procedure TestThread.execute;
begin
Synchronize(domessage);
end;

procedure TestThread.domessage;
begin
Form1.Memo1.lines.add(FileName);
end;

constructor TestThread1.Create(Suspend:boolean;FName:string);
begin
inherited Create(Suspend);
FileName:=FName;
FreeOnTerminate:=True;
end;

procedure TestThread1.execute;
begin
Synchronize(domessage);
end;

procedure TestThread1.domessage;
begin
Form1.Memo1.lines.add(FileName);
end;

procedure TForm1.Button1Click(Sender: TObject);
var TestTh:TestThread;
i:integer;
begin
For i:=0 to 255do
begin
TestTh :=TestThread.Create(True,Inttostr(i));
TestTh.Resume;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var TestTh:TestThread1;
i:integer;
begin
For i:=0 to 255do
begin
TestTh :=TestThread1.Create(True,Inttostr(i));
TestTh.Resume;
end;
end;

end.
 
我也正在学,看萧大给我的例子。
来自:萧月禾, 时间:2002-1-31 20:14:00, ID:899255
给你一个线程的测试例子你就明白了
在Form上有2组一样的控件,每组都有一个Edit和两个Button
一个Button开始一个线程,另一个结束这个线程
同时在另一组中也同时可以进行这样的操作
调用一个线程类
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TTest = class(TThread)
public
edt: TEdit;
procedure Execute;override;
end;

TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Edit2: TEdit;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
t1,t2: TTest;
public
{ Public declarations }
end;

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

{ TTest }
procedure TTest.Execute;
var
I: Integer;
begin
for I := 0 to 1000000do
begin
edt.Text := IntToStr(I);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
t1 := TTest.Create(true);
//降低优先级,否则两个线程一起快速运行时容易死锁
t1.Priority := tpLower;
t1.edt := Edit1;
t1.Resume;//开始
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
t1.Suspend;
//停止
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
t2 := TTest.Create(true);
t2.Priority := tpLower;
t2.edt := Edit2;
t2.Resume;//开始
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
t2.Suspend;
//停止
end;

end.

 
不要这一句.
procedure TestThread1.execute;
begin
// Synchronize(domessage);
do
message;
end;
当然有可能会造成冲突,你还需要设置一个互斥变量保证
同一时刻只能一个thread访问memo1
 
线程太多会导致系统资源严重下降,而且DELPHI的多线程并不稳定,我编的多线程
访问数据库程序在其它程序运行很容易出错。
 
Synchronize(domessage);
本来就是互斥访问,想快也快不起来!
能不能在进程中发消息;然后在消息相应过程中domessage;
 
procedure TestThread1.execute;
var
i:integer;
begin
for i:=0 to 255do
Synchronize(domessage);
end
调用时去掉那个循环。
 
多人接受答案了。
 
后退
顶部