一个简简单单的多线程监控,仅仅建立串口监听,并判断入口缓冲区数据是否大于256,是则读串口数据到本线程的缓冲区内,算是个简单的Demo(利用的是WinApi来打开串口,采用的是同步监听的方式)
---------------------------------------------------------------------------
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
lboxThreads: TListBox;
btnStartTheThread: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnStartTheThreadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses uComThread;
{$R *.dfm}
var
threads:array[0..15] of TComThread;
procedure TForm1.btnStartTheThreadClick(Sender: TObject);
var
strComX:string;
begin
strComX :=Format('Com%d',[lboxThreads.ItemIndex+1]);
if not Assigned(threads[lboxThreads.ItemIndex]) then
begin
threads[lboxThreads.ItemIndex] :=TComThread.Create(strComX);
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i:Integer;
begin
for i:=0 to lboxThreads.Count-1 do
begin
if Assigned(threads[lboxThreads.ItemIndex]) then
begin
threads[lboxThreads.ItemIndex].Destroy;
threads[lboxThreads.ItemIndex] :=nil;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
for i:=0 to lboxThreads.Count-1 do
threads[lboxThreads.ItemIndex] :=nil;
end;
end.
---------------------------------------------------------------------------
unit uComThread;
interface
uses
Classes,Windows, SysUtils;
type
TComThread = class(TThread)
private
{ Private declarations }
FComX :THandle;
FStrComX:string;
cache :array[0..255] of Byte;
protected
procedure Execute; override;
public
constructor Create(const AStrComX:string);overload;
destructor Destroy;override;
end;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TComThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ TComThread }
constructor TComThread.Create(const AStrComX:string);
begin
FStrComX :=AStrComX;
FComX :=CreateFile(PChar(FStrComX),
GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if FComX=INVALID_HANDLE_VALUE then
raise Exception.Create('Can not open '+FStrComX);
if not SetupComm(FComX, 4096, 4096) then //建立读写缓冲区
begin
CloseHandle(FComX);
raise Exception.Create('Can not SetupComm!');
end;
//清空读写缓冲区
PurgeComm(FComX, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR);
inherited Create(false);
end;
destructor TComThread.Destroy;
begin
CloseHandle(FComX);
end;
procedure TComThread.Execute;
var
error
WORD;
theComStat:COMSTAT;
begin
{ Place thread code here }
while not Terminated do
begin
ClearCommError(FComX,error,@theComStat);
if theComStat.cbInQue>=256 then
ReadFile(FComX,cache,256,error,nil);
end;
end;
end.
---------------------------------------------------------------------------
object Form1: TForm1
Left = 0
Top = 0
Width = 532
Height = 254
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object lboxThreads: TListBox
Left = 0
Top = 0
Width = 73
Height = 220
Align = alLeft
ItemHeight = 13
Items.Strings = (
'Thread-1'
'Thread-2'
'Thread-3'
'Thread-4'
'Thread-5'
'Thread-6'
'Thread-7'
'Thread-8'
'Thread-9'
'Thread-10'
'Thread-11'
'Thread-12'
'Thread-13'
'Thread-14'
'Thread-15'
'Thread-16')
TabOrder = 0
end
object btnStartTheThread: TButton
Left = 80
Top = 8
Width = 105
Height = 25
Caption = 'btnStartTheThread'
TabOrder = 1
OnClick = btnStartTheThreadClick
end
end
---------------------------------------------------------------------------