刚学线程,有些问题不懂啊,上次做了个串口通信的东西,很多不懂, hch_45(HCH ~ahong.net~)帮我解决了不少问题,在此感谢了。但是还有一些问题请教。
comm1是在线程里创建的,
但我要在主form里设置一个radiogroup和一个buttom,用来选择并打开通讯端口,请问怎么做?我自己搞了一个,但是我发现运行后,耗的内存不断增加,cpu使用率也一直是100%
,请哪位高手就我这个问题做个详细解答,感激不尽啊。我的程序如下: 主form:unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, TComm1,Unit2;type
  TForm1 = class(TForm)
    rdcom: TRadioGroup;
    Button2: TButton;
    Memo2: TMemo;
    Button3: TButton;
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;
implementation{$R *.dfm}
procedure TForm1.Button3Click(Sender: TObject);
begin
close;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
readthread:=treadthread.create(false);
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
readthread.Free;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
readthread.opens;
end;end.
线程:
unit Unit2;interfaceuses
  Classes,tcomm1;type
  treadthread = class(TThread)  procedure opens ;
  private
    comm1:tcomm;
    temp:string;
    procedure readport;
  protected
    procedure Execute; override;
  end;
var
  readthread:treadthread;implementationuses unit1;
procedure treadthread.Execute;
begin
  comm1:=tcomm.create(nil); try
   while not terminated do
  begin
  temp:=comm1.input;
  synchronize(readport);
  end;
  finally
  comm1.free;
  end;
end;procedure treadthread.readport;
begin
form1.Memo2.Text:=temp;
end;procedure treadthread.opens;
begin
case form1.rdcom.ItemIndex of    
  0:comm1.commport:=pncom1;
  1:comm1.CommPort:=pncom2;
end;
comm1.PortOpen:=true;
end;
end.

解决方案 »

  1.   

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    readthread:=treadthread.create(false);---->>true
    多加一行:readthread.freeonterminated:=true;
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    readthread.Free;------->>readthread.terminate;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
    readthread.opens;------------>>readthread.resume;
    end;
      

  2.   

    我上面改的不一定对,因为一下还尚未明了:procedure treadthread.opens;
    begin
    case form1.rdcom.ItemIndex of    
      0:comm1.commport:=pncom1;
      1:comm1.CommPort:=pncom2;
    end;
    comm1.PortOpen:=true;
    end;
    虽然是在线程中定义的,但是函数永远是资源,哪个线程调用它,她才再哪个线程里面执行。
    你再button2 click的时候调用它,而button2click是主线程调用的,opens自然再主线程中运行。   while not terminated do 
      begin
      temp:=comm1.input;<<============这个是阻塞的么?即便是阻塞,那么它里面有没有耗时很短的循环呢?这就是cpu 使用率居高不下的原因。
      synchronize(readport);  
      end;
      finally
      comm1.free;
      end;
      

  3.   

    var
    msg:tmsg;
    begin
       while not terminated and getmessage(msg,....) do//这样由于getmessage是阻塞的,就是线程队列没有消息就不返回,而你再主线程里面用postthreadmessage代替readthread.resume来控制工作线程多好。
      begin
      temp:=comm1.input;
      synchronize(readport);  
      end;
      finally
      comm1.free;
      end;
      

  4.   

    还有一点,我个人总觉得synchronize有时候效率很低,因为所有线程都是考主线程来协调的,要想协调,都得通过主线程,而且是在主线程不忙的时候一个一个协调执行。而一旦主线程由于某些意外问题阻塞了,其他线程会很痛苦的,比如flashget,当bandwidth很大的时候,界面为了得到各个线程的状态忙得不得了,甚至有时候添加下载任务都很困难,主线程不就是为了显示么,自己的节奏干嘛被工作线程控的快慢制?用个timer循环访问各个线程,interval根据线程的多少自动设置。或者用一个“监视线程”代替主线程循环访问各个下载线程,得到数据就给主线程发消息,这样就能够分担主线程为了同步访问下载线程的数据需要等待的时间。另外,把添加任务做成单独的进程,用filemapping或者wm_copydata来通信多好。当然flashget不一定是delphi做的,不过思想一样。
      

  5.   

    看你这意思temp:=comm1.input;应该是个耗时很短的操作,为啥不再主线程里面进行?
      

  6.   

    我也试过,在主线程里要用timer循环,这样在运行的时候会有闪烁啊。有什么解决办法吗?
      

  7.   

    运行的时候闪烁跟线程有什么关系?哪里闪烁?你用了listview?
      

  8.   

    我不用线程,在主form里用timer循环,运行时有闪烁,因为要不断的读端口,interval设置的时间越短,闪得越厉害。