循环多线程通信!(100分)

  • 主题发起人 主题发起人 smhp
  • 开始时间 开始时间
S

smhp

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟初学者,请高手指点!
有两个线程,A产生随机数,填入数组,当数组满时,
线程A通知绘制线程B,同时线程A挂断,
线程B将数组绘制出,画完后,B通知A继续产生随机数,
B挂断,如果用户未中断,则继续循环!
哪位先生能帮助我完成这个作业?谢谢!
 
小弟初学者,请高手指点!
 
怎么没有人啊!
 
使用消息
 
Tevent怎么用啊!
 
这是我写的代码,在NT/Delphi5 下测试通过,我用了消息处理,感觉不是太好,因为用了
几个全局变量,你先看看再说吧。
//线程单元
unit Unit2;
interface
uses
Classes, Windows, Messages, Sysutils;
const UM_RESUMEA = WM_USER + 1024;
const UM_RESUMEB = WM_USER + 1025;
type
TAThread = class(TThread)
private
protected
procedure Execute;
override;
end;

TBThread = class(TThread)
private
protected
procedure Execute;
override;
procedure ShowArrayVal;
public
constructor Create(CreateSuspended: Boolean);
end;

var
AArray : Array [1..10] of integer;
implementation
uses Unit1;
{ TSThread }
procedure TAThread.Execute;
var
i : Integer;
begin
FreeOnTerminate := True;
while not Terminateddo
begin
Randomize;
for i := 1 to 10do
begin
AArray := Random(100);
end;
PostMessage(Form1.Handle,UM_RESUMEB,0,0);//注意这里不能用SendMessage
Suspend;
end;
end;

{ TBThread }
constructor TBThread.Create(CreateSuspended: Boolean);
begin
inherited Create(True);
end;

procedure TBThread.Execute;
begin
while not Terminateddo
begin
Synchronize(ShowArrayVal);
PostMessage(Form1.Handle,UM_RESUMEA,0,0);//注意这里不能用SendMessage
Suspend;
end;
end;

procedure TBThread.ShowArrayVal;
var
i : Integer;
begin
Form1.Memo1.Clear;
for i := 1 to 10do
begin
Form1.Memo1.Lines.Add(IntToStr(AArray));
end;
end;

end.

//主程序单元
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Unit2;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
protected
procedure UMResumeA(var Msg : TMessage);
message UM_RESUMEA;
procedure UMResumeB(var Msg : TMessage);
message UM_RESUMEB;
end;

var
Form1: TForm1;
implementation
var
AThread : TAThread;
BThread : TBThread;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
AThread := TAThread.Create(False);
BThread := TBThread.Create(True);
end;

procedure TForm1.UMResumeA(var Msg: TMessage);
begin
AThread.Resume;
end;

procedure TForm1.UMResumeB(var Msg: TMessage);
begin
BThread.Resume;
end;

end.

 
忘了去掉一些东西,又改了一下。
 
感谢教父同志,怎么改用EVENT处理?
 
建立两个全局TEvent, EA, EB, 全初始化成无信号。TEvent.Create(nil,false ,false, '');
线程A.Execute
begin
while xxxdo
begin
EA.Waitfor(INFINITE);
//产生随机数
//...
EB.SetEvent;
end;
end;

线程B.Execute
begin
while xxxdo
begin
EB.Waitfor(INFINITE);
//处理随机数
// ....
EA.SetEvent;
end;
end;

在开始该过程时,主线程要把EA置为有信号 EA.SetEvent;
该问题类似于操作系统原理中讲的生产者和消费者的问题,但更简单一些。
可有帮助?
 
jiangyiquan同志:能给个具体点的例子吗?不胜感激!
 
本人星期一要交作业了,希望各位高手能帮忙啊!
 
jiangyiquan同志:
EA,EB在哪里定义,他们的初始化在哪里做?
能否接着教父同志的代码,您能详细的讲一下吗?
谢谢!
 
希望各位高手能帮忙啊!
 
希望各位高手能帮忙啊!
[?][?][?][?][?][?][?]
 
已经够具体了,关键是你要看一下Event的用法,找一本Windows的参考书看看吧。
线程A.Execute
begin
while xxxdo
begin
EA.Waitfor(INFINITE);
//产生随机数
//...
for i := 0 to FULL - 1do
begin
数组 := 随机数;
end;

EB.SetEvent;
end;
end;

线程B.Execute
begin
while xxxdo
begin
EB.Waitfor(INFINITE);
//处理随机数
// ....
for i := 0 to FULLdo
begin
绘制(数组);

end;
或不用for循环,直接调用自己编写函数
EA.SetEvent;
end;
end;

 
jiangyiquan同志:很不好意思,EVENT的用法我找了很多书看了,但是因为我学DELPHI才
几天(以前搞VB和C,都是非OOP的),所以对于我来说,DELPHI就难在变量定义、变量的
作用范围、变量的释放、各模块之间的关系,所以请您告诉我EA、EB怎么定义,在哪里定
义,怎么释放,还有事件的初始化在哪里做!谢谢您对一个入门者的帮助引导!
 
晚上写一个完整的吧。
 
//////////////////////
/////TestEvent.dpr
program TestEvent;
uses
Forms,
MainFrm in 'MainFrm.pas' {frmMain},
Thrd in 'Thrd.pas';
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end.

/////////////////////////////////////
///Thrd.pas
unit Thrd;
interface
uses
Classes, Windows, syncobjs;
type
TTestThrdA = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;

TTestThrdB = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;

const
FULL = 100;
var
aryInt: array[1..FULL] of integer;
EA, EB: TEvent;
ThrdA: TTestThrdA;
ThrdB: TTestThrdB;
implementation
uses
MainFrm;
procedure TTestThrdA.Execute;
var
i: Integer;
begin
while not Terminateddo
begin
if EA.Waitfor(INFINITE) = wrAbandoned then
Exit;
for i := 1 to FULLdo
aryInt := Random(100);
EB.SetEvent;
end;
end;

procedure TTestThrdB.Execute;
var
i: Integer;
begin
while not Terminateddo
begin
if EB.Waitfor(INFINITE) = wrAbandoned then
Exit;
frmMain.Canvas.MoveTo(0, 0);
for i := 1 to FULLdo
begin
frmMain.Canvas.LineTo(i * 2, aryInt);
Sleep(10);
end;

EA.SetEvent;
end;
end;
end.

////////////
////MainFrm.pas
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, syncobjs;
type
TfrmMain = class(TForm)
btn: TButton;
procedure btnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
b: BOOL;
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
implementation
uses
THrd;
{$R *.DFM}
procedure TfrmMain.btnClick(Sender: TObject);
begin
if not b then
begin
Self.Repaint;
EA := TEvent.Create(nil,false ,false, '');
EB := TEvent.Create(nil,false ,false, '');
ThrdA := TTestThrdA.Create(True);
ThrdB := TTestThrdB.Create(True);
ThrdA.FreeOnTerminate := True;
ThrdB.FreeOnTerminate := True;
ThrdA.Resume;
ThrdB.Resume;
EA.SetEvent;
btn.Caption := 'END';
end
else
begin
EA.Free;
EB.Free;
ThrdA.Terminate;
ThrdB.Terminate;

btn.Caption := 'begin
';
end;

b := not b;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
b := False;
btn.Caption := 'begin
';
end;

end.

////////////////////////////
/////MainFrm.dfm
object frmMain: TfrmMain
Left = 160
Top = 113
Width = 498
Height = 351
Caption = 'frmMain'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object btn: TButton
Left = 64
Top = 240
Width = 75
Height = 25
Caption = 'begin
'
TabOrder = 0
OnClick = btnClick
end
end
//没仔细调试,但可运行。
 
后退
顶部