请教大家一个关于串口多线程的问题:如何正确关闭线程和串口,请大家帮我看下我代码那里出了问题,谢谢

ysysbaobei 2010-11-21 06:26:08
请教大家一个关于串口多线程的问题:如何正确关闭线程和串口,请大家帮我看下我代码那里出了问题,谢谢

开发环境:VC6.0
要求:用api写一个关于串口的多线程程序

我的问题:我关闭后,再打开,就会程序运行占用整个CPU吧,使用不了电脑的其他地方了

代码如下:

打开线程按钮函数:
hCom=CreateFile(_T("COM3"),//COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式
NULL);

if(hCom==(HANDLE)-1)
{
AfxMessageBox(_T("打开COM7失败!"));
return FALSE;
}

SetupComm(hCom,1024,1024); //输入缓冲区和输出缓冲区的大小都是1024

COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
//在读一次输入缓冲区的内容后读操作就立即返回,
//而不管是否读入了要求的字符。


//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=3000;
SetCommTimeouts(hCom,&TimeOuts); //设置超时

DCB dcb;
GetCommState(hCom,&dcb);

dcb.BaudRate=9600; //波特率为9600
dcb.ByteSize=8; //每个字节有8位
dcb.Parity=NOPARITY; //无奇偶校验位
dcb.StopBits=ONESTOPBIT; //1个停止位

SetCommState(hCom,&dcb);

PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);

//CWinThread *rxThread = AfxBeginThread(ReceiveDataThread, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); // 创建并挂起线程
rxThread = AfxBeginThread(ReceiveDataThread, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); // 创建并挂起线程

if(rxThread==NULL)
{
CloseHandle(hCom);
return false;
}
else
{
rxThread->ResumeThread(); // 恢复线程运行
}

//OVERLAPPED m_osRead;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

memset(&m_osWrite,0,sizeof(OVERLAPPED));
m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

SetTimer(SEND_DATA_BY_TIMER,1000,NULL);

return true;



关闭线程按钮函数
KillTimer(SEND_DATA_BY_TIMER);

if (rxThread != NULL)
{
SetEvent(m_osWrite.hEvent); /* 通知串口接收线程退出 */
CloseHandle(m_osWrite.hEvent);

SetEvent(m_osRead.hEvent); /* 通知串口接收线程退出 */
WaitForSingleObject(rxThread, 500); /* 等待线程退出 */

//CloseHandle(rxThread); /* 关闭接收线程句柄 */
CloseHandle(m_osRead.hEvent); /* 关闭线程退出事件句柄 */
rxThread = NULL;
}

if (hCom != INVALID_HANDLE_VALUE)
{
SetCommMask(hCom, 0);
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/发缓冲 */
CloseHandle(hCom); /* 关闭串口操作句柄 */
hCom = INVALID_HANDLE_VALUE;
}

return;



另外的函数:
1。发送数据函数:
char lpOutBuffer[7];

memset(lpOutBuffer,'\0',7);
lpOutBuffer[0]='0';
lpOutBuffer[1]='1';
lpOutBuffer[2]='2';
lpOutBuffer[3]='3';
lpOutBuffer[4]='4';
lpOutBuffer[5]='5';
lpOutBuffer[6]='6';

DWORD dwBytesWrite=7;

COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;

ClearCommError(hCom,&dwErrorFlags,&ComStat);

bWriteStat=WriteFile(hCom,lpOutBuffer,
dwBytesWrite,& dwBytesWrite,&m_osWrite);

if(!bWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(m_osWrite.hEvent,1000);
}
}


2。 定时器函数:定时发送 “1。发送数据函数”
---------------------------------------------------------


我的问题是,点击打开线程按钮函后,收发数据正常;
现在关闭串口线程,正常;
再点打开线程函数,感觉程序占用了整个CPU,用不了电脑的任何地方,只能重启机器,任务管理器都使用不了。
估计是关闭线程函数有问题?大家帮帮忙!!!
...全文
279 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ysysbaobei 2012-04-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
楼主您好:我现在在写一个通信程序,要与两个串口通信,单独运行每一个时没问题,但不能同时运行两个。我也不会多线程,我希望楼主您能给一下您的程序,我也学习一下多线程串口是怎么写的,先谢谢了。我的邮箱287645048@qq.com。希望楼主能帮帮忙。
[/Quote]

但不能同时运行两个 --- 具体是指?
mengzhendream 2012-04-07
  • 打赏
  • 举报
回复
楼主您好:我现在在写一个通信程序,要与两个串口通信,单独运行每一个时没问题,但不能同时运行两个。我也不会多线程,我希望楼主您能给一下您的程序,我也学习一下多线程串口是怎么写的,先谢谢了。我的邮箱287645048@qq.com。希望楼主能帮帮忙。
ysysbaobei 2011-10-08
  • 打赏
  • 举报
回复
不知道楼上的问题解决没,若未解决,留言,我再去翻一下以前的代码,
guyuexuangyx 2011-08-22
  • 打赏
  • 举报
回复
能不能把你的源代码发我邮箱286810303@qq.com,我也刚学,最近要做这个程序,很多不懂,谢谢了啊!!!
ysysbaobei 2010-12-11
  • 打赏
  • 举报
回复
问题找到了,
那个 while (true)
有问题,弄个标志位来控制,就可以了;

开启多线程时,bContinueFlag = true;
比如 while (bContinueFlag)
在关闭线程时,bContinueFlag = false;

这样就避免了正确关闭了线程,while还是一直在循环,导致CPU被占用

结贴了,谢谢大家
ysysbaobei 2010-11-22
  • 打赏
  • 举报
回复
顶下,大家帮忙看看

在.cpp的头部,定义了几个全局变量,如下:

//全局变量
HANDLE hCom; // 串口句柄
OVERLAPPED m_osRead; // 读重叠
OVERLAPPED m_osWrite; // 写重叠
CWinThread *rxThread; // 串口接收数据线程
ysysbaobei 2010-11-22
  • 打赏
  • 举报
回复
接收串口线程函数:

// 工作者线程,负责监视串行口
UINT ReceiveDataThread(LPVOID pParam)
{
CThreadCommDlg *pRxThread=(CThreadCommDlg*)pParam;

OVERLAPPED m_osRead;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

COMSTAT ComStat;
DWORD dwErrorFlags;

char str[512];
memset(str,'\0',512);
DWORD dwBytesRead=500;//读取的字节数
DWORD dwBytesHaveRead = 0;//读取的字节数
BOOL bReadStat;

CString strReceiveData;

ClearCommError(hCom,&dwErrorFlags,&ComStat);

while (true)
{
memset(str,'\0',512);

//dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue);

bReadStat=ReadFile(hCom,str,dwBytesRead,&dwBytesHaveRead,&m_osRead);
//bReadStat=ReadFile(hCom,str,dwBytesRead,&dwBytesRead,&m_osRead); // 这样会导致接收不到数据:原因,while(true)第一次执行时,就会把待读取字符数dwBytesRead置为0

/*if (0 != dwBytesHaveRead)
{
CString strTemp;
strTemp.Format(L"%d", dwBytesHaveRead);

AfxMessageBox(strTemp);
}*/

if(!bReadStat)
{
if(GetLastError()==ERROR_IO_PENDING)
//GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作
{
WaitForSingleObject(m_osRead.hEvent,2000);
//使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟
//当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号
}
}

/*PurgeComm(hCom, PURGE_TXABORT|
PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);*/

//strReceiveData += str;

if ('\0' != str[0])
{
//AfxMessageBox(strReceiveData);

::SendMessage(pRxThread->m_hWnd, COM_RX_DATA, (WPARAM)str, (LPARAM)dwBytesHaveRead);
}

//pRxThread->m_receive_data += str;
//pRxThread->UpdateData(false); // 程序运行到此处会出错
}

return 0;
}
ysysbaobei 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sd6814466 的回复:]
你的接受线程代码呢?不知道你怎么关闭的线程

SetEvent(m_osWrite.hEvent); /* 通知串口接收线程退出 */
CloseHandle(m_osWrite.hEvent);

SetEvent(m_osRead.hEvent); /* 通知串口接收线程退出 */
由你这里看,由两个事件来通知线程退出?不知道如何实现的

WaitForSingleObject……
[/Quote]

能不能给出详细的代码呢?比较急。
m_tornado 2010-11-21
  • 打赏
  • 举报
回复
~
sd6814466 2010-11-21
  • 打赏
  • 举报
回复
你的接受线程代码呢?不知道你怎么关闭的线程

SetEvent(m_osWrite.hEvent); /* 通知串口接收线程退出 */
CloseHandle(m_osWrite.hEvent);

SetEvent(m_osRead.hEvent); /* 通知串口接收线程退出 */

由你这里看,由两个事件来通知线程退出?不知道如何实现的

WaitForSingleObject(rxThread, 500); /* 等待线程退出 */
由这里看,似乎等待的是线程句柄?一般等待的是事件句柄吧?有没有作用不知道。。。

你也不一定非要关闭线程,关闭串口的时候,把线程挂起就可以了,开启了串口继续工作
ysysbaobei 2010-11-21
  • 打赏
  • 举报
回复
顶下,大家帮帮忙

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧