使用CloseHandle关闭串口句柄后win2k系统使用率一直为100%???(100分)

  • 主题发起人 主题发起人 ykjiang
  • 开始时间 开始时间
Y

ykjiang

Unregistered / Unconfirmed
GUEST, unregistred user!
各位高手:
我遇到一个奇怪的问题:使用Createfile创建了一个com1的handle类型的句柄hcom1,使用完之后用closehandle(hcom1)关闭,我观察到运行完closehandle(hcom1)后CPU的占有率一下就跳到100%,此时我的应用程序还在运行其它功能,请各位高手指教。
 
我用过这个做过串口程序呀,怎么没发现有这个问题呢,是不是你还用其他什么的函数了
 
我使用了中断方式接收数据
 
应用程序的资源释放!
 
刀剑如梦能否详细指点一下,我的源程序如下://设置串行口com1
...
InitializeCom(com1);
...

function TfmMain.InitializeCom(com:String):boolean;
var
Ok:Boolean;
dcb:TDCB;
str:string;
begin
result:=True;
hNewCommFile:=CreateFile(Pchar(com),GENERIC_READ or GENERIC_WRITE,0,nil,
OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
if hNewCommFile=INVALID_HANDLE_VALUE then
begin
result:=False;
str:= 'ERROR: open '+rERTU[1].com+' error';
AddMessage(str);
//MessageBox(0,pchar(str),'Notice',MB_OK);
exit;
end;
OK:=SetCommMask(hNewCommFile,EV_RXCHAR);
if(not Ok) then
begin
result:=False;
AddMessage('ERROR: SetCommMask error(init ...)');
//MessageBox(0,'SetCommMask error(init ...)','Notice',MB_OK);
exit;
end;
//设置缓冲区大小及主要参数
SetupComm(hNewCommFile,1024,1024);
GetCommState(hNewCommFile,dcb);
dcb.BaudRate:=2400;
dcb.ByteSize:=8;
dcb.Parity:=NOPARITY;
dcb.StopBits:=ONESTOPBIT;
Ok:=SetCommState(hNewCommFile,dcb);
if(not Ok) then
begin
AddMessage('ERROR: SetCommState error');
result:=False;
end;
end;

//中断接收初始化
function TfmMain.InitReceive:boolean;
var
ThreadID:DWORD;
begin
result:=True;
iBufCount:=1; receivedcount:=0; ReceiveData:=0;
FillChar(Read_Os,SizeOf(Read_Os),0);
Read_Os.Offset:=0;
Read_Os.OffsetHigh:=0;
//创建Overlspped Read 事件
Read_Os.hEvent:=CreateEvent(nil,true,False,nil);
if Read_Os.hEvent=null then
begin
CloseHandle(hNewCommFile);
AddMessage('ERROR: CreateEvent error');
result:=False;
//MessageBox(0,'CreateEvent error','Notice',MB_OK);
exit;
end;
//创建PostMessage 事件
Post_Event:=CreateEvent(nil,True,True,nil);
if Post_event=null then
begin
CloseHandle(hNewCommFile);
CloseHandle(Read_Os.hEvent);
AddMessage('ERROR: CreateEvent error');
result:=False;
//MessageBox(0,'CreateEvent error','Notice',MB_OK);
exit;
end;
Com_Thread:=CreateThread(nil,0,@CommWatch,nil,0,ThreadID);
//建立通信监视线程
if(Com_Thread=0) then
begin
AddMessage('ERROR: CreateThread function can not work');
result:=False;
//MessageBox(Handle,'CreateThread function can not work',nil,MB_OK);
end;
EscapeCommFunction(hNewCommFile,SETDTR);
end;

//通信监视线程
procedure CommWatch(Ptr:Pointer);stdcall;
var
dwEvtMask,dwTranser:DWord;
OK:Boolean;
Os:Toverlapped;
begin
Receive:=True;
FillChar(Os,SizeOf(Os),0);
Os.hEvent:=CreateEvent(nil,True,False,nil);
//创建重叠读事件对象
if Os.hEvent=null then
begin
MessageBox(0,'Os.Event Create Error!','Notice',MB_OK);
exit;
end;
if(not SetCommMask(hNewCommFile,EV_RXCHAR)) then
begin
MessageBox(0,'SetCommMask Error!','Notice',MB_OK);
exit;
end;
while (Receive) do
begin
dwEvtMask:=0;
//等待设置好的通信事件发生,由于有个Os (Os:Toverlapped),表示进行的是overlapped
//等待,不会被这个等待堵塞住
if not WaitcommEvent(hNewCommFile,dwEvtMask,@Os)then
begin
if ERROR_IO_PENDING= GetLastError then
GetOverlappedResult(hNewCommFile,Os,dwTranser,True);
end;
if((dwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
begin
WaitForSingleObject(Post_event,INFINITE);
//等待允许传递WM_COMMNOTIFY 通信消息
ResetEvent(Post_Event);
//处理WM_COMMNOTIFY消息,不再发送WM_COMMNOTIFY消息
OK:=PostMessage(fmMain.Handle,WM_COMMNOTIFY,hNewCommFile,0);
if (not OK) then
begin
MessageBox(0,'PostMessage,Error!','Notice',MB_OK);
exit;
end;
end;
end;
CloseHandle(Os.hEvent);
//关闭重叠读事件对象
end;

//消息处理函数
procedure TfmMain.WM_COMMNOTIFY(var message:TMessage);
var
CommState:ComStat;
dwNumberOfBytesRead:DWord;
ErrorFlag:Dword;
i:Dword;
InputBuffer:Array[0..1024] of Byte;
begin
//ClearCommError 恢复通信错误信息并报告当前的通信设备状态.当通信错误发生时
//调用此函数,它会清除附加的I/O操作的设备错误标志
if not ClearCommError(hNewCommFile,ErrorFlag,@CommState) then
begin
MessageBox(0,'ClearCommErro!','Notice',MB_OK);
PurgeComm(hNewCommFile,Purge_Rxabort or Purge_Rxclear);
exit
end;
if(CommState.cbInQue>0) then
begin
fillchar(InputBuffer,CommState.cbInQue,#0);
//接收通信数据
if (not ReadFile(hNewCommFile,InputBuffer,CommState.cbInQue,
dwNumberOfBytesRead,@Read_Os)) then
begin
ErrorFlag:=GetLastError();
if(ErrorFlag<>0) and (ErrorFlag<>ERROR_IO_PENDING) then
begin
{MessageBox(0,'ReadFile Error!','Notice',MB_OK);
Receive:=False;
CloseHandle(Read_Os.hEvent);
CloseHandle(Post_Event);
CloseHandle(hNewCommFile);
exit}
end
else
begin
WaitForSingleObject(hNewCommFile,INFINITE);
//等待操作完成,等待设置好的Event 发生
GetOverlappedResult(hNewCommFile,Read_Os,dwNumberOfBytesRead,False);
end;
end;
if dwNumberOfBytesRead>0 then
begin
Read_Os.Offset:=read_Os.offset+dwNumberOfBytesRead;
ReceiveData:=Read_Os.Offset;
for i:=0 to dwNumberOfBytesRead do
//begin
ReceiveBuffer[iBufCount+i]:= InputBuffer;
//AddMessage(inttohex(ReceiveBuffer[iBufCount+i],2));
//end;
iBufCount:=iBufCount + dwNumberOfBytesRead;
AddToMemo(dwNumberOfBytesRead);
//处理接收的数据
end;
end;
SetEvent(Post_Event);
//允许发送下一个WM_COMMNOTIFY 消息
end;

//关闭串行口
procedure TfmMain.CloseRS232Com;
begin
PurgeComm(hNewCommFile,PURGE_RXABORT+PURGE_RXCLEAR);
CloseHandle(com_thread);
showmessage('After CloseHandle com_thread');
CloseHandle(Post_Event);
showmessage('After CloseHandle Post_Event');
CloseHandle(Read_Os.hEvent);
showmessage('After CloseHandle Read_Os.hEvent');
CloseHandle(hNewCommFile);
showmessage('After CloseHandle hNewCommFile');
end;


//通过观察,在执行完 CloseHandle(hNewCommFile);后 CPU的使用率就一下上升到100%
//我的程序大致流程是:打开串口 -> 发送、接收数据 -> 关闭串口 -> 打开串口 -> 发送、接收数...(必须这样)
//哪位高手有更好的建议本人一定多多加分。
 
你的代码太长了,没有细看。你能不能肯定你的线程释放了(回掉函数)。我有一个例子修改一下就副和你的要求,需要留下email;
 
谢了chen_cch,我的email是sjyk@sina.com
 
谢谢 Chen_cch, 谢谢各位
 
后退
顶部