如何正确的关闭 MFC 线程

.关于MFC的线程

  1.MFC的线程有两种,一种称为Work线程,一种称为UI线程。一般情况下Work线程与UI线程的区别主要在于UI线程有消息队列(并不是有没有界面,这点要注意,UI线程也是可以没有界面的)。

  2.创建这两种线程的区别也不大,可以从创建函数看出。

1.	// Work线程   
2.	CWinThread* AfxBeginThread(  
3.	      AFX_THREADPROC pfnThreadProc,  
4.	      LPVOID pParam,  
5.	      int nPriority = THREAD_PRIORITY_NORMAL,  
6.	      UINT nStackSize = 0,  
7.	      DWORD dwCreateFlags = 0,  
8.	      LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL  
9.	     );  
10.	  
11.	// UI线程   
12.	CWinThread* AfxBeginThread(  
13.	      CRuntimeClass* pThreadClass,  
14.	      int nPriority = THREAD_PRIORITY_NORMAL,  
15.	      UINT nStackSize = 0,  
16.	      DWORD dwCreateFlags = 0,  
17.	      LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL  
18.	     );  

. 结束线程前的注意事项

  在结束一个线程前,只有一点要注意,那就是m_bAutoDelete 的状态。(什么?不知道m_bAutoDelete ?!!快去查阅MSDN吧)。

  m_bAutoDelete = FALSE;// 表示你自己管理 CWind 对象,包括它的清理   

  m_bAutoDelete = TRUE;  // 默认值, 系统会自己清理 CWind 对象  

当然还包括CloseHandle()ExitInstance()等等一堆函数的调用。

m_bAutoDelete = FALSE; 那么就一定要记得自己在用完后调用delete删除创建线程的对象,这一点极为重要,因为不调用delete一定会有内存泄漏问题

.正确的结束一个Work线程

  因为Work线程是一个全局函数,或者是一个Static函数,所以它的运行完成也就是它的正常退出了。(什么?不明白,示例代码如下)

  1.情况一:

1.	UINT WorkFunc(LPVOID pParam)  
2.	{  
3.	  // 工作   
4.	  ......  
5.	   return 0;  // 就算正常退出了,简单吧   
6.	}  

.情况二:

Work线程是个死循环或一时半会儿出不来,这时要主线程要发个消息给Work线程,让他退出。

1.	UINT WorkFunc(LPVOID pParam)  
2.	{  
3.	  for(;;)  
4.	  {  
5.	   // ...   
6.	  if( WAIT_OBJECT_0 == WaitForSingleObject(m_hThread, INFINITE)} // 收到激发态的消息   
7.	    {  
8.	      return 0;//正常退出   
9.	     }  
10.	  
11.	 }//end for   
12.	    
13.	 return 0;  
14.	}  
关于主线程发一个激发态的消息给 Work 线程,有多种方法,如在主线程里调用 SetEvent() 等等,你想用什么都行,但是最好不要在 Work 线程里用 Busy loop 的方法。

.正确结束一个UI线程

  因为UI线程有消息队列,所以结束一个UI线程最好的方法是发一个WM_QUIT消息给消息队列,方法很多如:PostQuitMessage(),PostThreadMessage()等等。但是发出消息后最好等待看UI线程是否已经退出(很多人都没有提及这一点,但是实际工作中发现,加上这一点是多么的重要)

1.	// 主线程结束UI线程的代码   
2.	if(pThread)   
3.	{  
4.	  // 1. 发一个WM_QUIT 消息结 UI 线程   
5.	  pThread->PostThreadMessage(WM_QUIT, NULL, NULL);  
6.	                  
7.	 // 2. 等待 UI 线程正常退出   
8.	 if (WAIT_OBJECT_0 == WaitForSingleObject(pThread->m_hThread, INFINITE))  
9.	 {  
10.	    // 3. 删除 UI 线程对象,只有当你设置了m_bAutoDelete = FALSE; 时才调用   
11.	  delete   pThread;   
12.	 }  
13.	  
14.	}  

.关于几个问题的解答

.问:为什么我的UI线程没有调用ExitInstance()

答:最大的可能是你的WM_QUIT消息没有通知到UI线程。为了保险期间最好调用PostThreadMessage(),这样可以指定线程的ID。当然如果你对消息比较熟悉的话,也可以抛一个消息到最顶层。

 

.问:为什么我的UI线程没有调用析构函数?

答:检查看你的m_bAutoDelete =FALSE,如果是的话,那么看你的线程对象是否已经delete了。一般情况下调用delete会调用析构函数

 

.问:在UI线程中没有调用WaitForSingleObject(),会怎么样?

答:我们知道在PostMessage()之后,函数会马上返回,如查没有wait...(),那么紧接着就调用了delete很有可能对象做的退出操作过程还没有完成时,又把对象delete掉了,结果还是没有正常结束。(注:WM_QUIT消息之后会触发一堆函数,这个时间是不定的,所以最好Wait...才是正道。)

 

.最后不愿提的函数

几乎每本讲线程的书都会提到下面的函数:

  void AfxEndThread(UINT nExitCode);

  TerminateThread();

......还有其它的一些极端的函数,建议:不要用!!





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MFC(Microsoft Foundation Classes)是微软公司为Windows操作系统开发的一套面向对象的C++类库。它能够使开发者更轻松地创建Windows图形用户界面(GUI)应用程序。 在MFC中,实现多串口通信可以通过使用CSerialPort类来实现。CSerialPort类封装了串口的操作,可以通过调用其方法来打开、关闭、读取和写入串口数据。 而要实现多线程,则可以利用MFC提供的CWinThread类。通过创建多个CWinThread对象,每个对象分别处理一个串口的通信任务。每个CWinThread对象使用独立的线程来执行任务,以避免阻塞主线程。 具体实现步骤如下: 1. 创建一个主线程,用于处理用户界面和整体程序的控制逻辑。 2. 创建多个CWinThread对象,每个对象分别处理一个串口通信任务。 3. 在每个CWinThread对象中,使用CSerialPort类的实例进行串口的打开、配置、读取和写入等操作。 4. 确保每个CWinThread对象都在独立的线程中执行任务,以防止串口通信阻塞主线程。 5. 如果需要在主线程中对串口通信的数据进行处理,可以使用MFC提供的同步机制来保证数据的正确访问。 总结起来,使用MFC实现多串口多线程的步骤主要包括创建主线程和多个CWinThread对象、配置串口参数、在每个CWinThread对象中进行串口通信操作,并进行数据的同步处理。这样可以使程序具备同时处理多个串口通信任务的能力。 ### 回答2: MFC是Microsoft Foundation Classes的简称,它是一个用于创建Windows应用程序的C++类库。多串口是指在一个应用程序中同时使用多个串口进行通信的功能。多线程是指在一个应用程序中同时运行多个线程的能力。 在MFC中实现多串口功能可以通过使用串口类(CSerialPort)和线程类(CWinThread)来实现。首先,我们可以创建多个CSerialPort对象,每个对象代表一个串口。然后,可以使用CWinThread创建多个线程,每个线程负责处理一个串口的通信操作。 在每个线程中,可以使用CSerialPort对象进行串口通信。每个线程通过调用CSerialPort类的成员函数来打开、关闭、发送和接收数据。可以使用线程同步机制(如事件、临界区或互斥量)来避免多个线程同时访问同一个串口对象。 在多线程环境下使用MFC多串口功能需要注意以下几点: 1. 使用线程同步机制来保证多个线程对同一个串口对象的访问安全; 2. 避免多个线程同时发送数据到同一个串口,以避免数据冲突; 3. 合理分配串口和线程资源,避免资源竞争和性能瓶颈; 4. 注意处理串口通信错误和异常情况,保证程序的稳定性和可靠性。 总之,借助MFC的类库,我们可以很方便地实现多串口多线程功能,提高应用程序的通信效率和并发处理能力。但在并发操作时,需要注意线程安全和资源管理等问题,以确保应用程序的稳定性和可靠性。 ### 回答3: MFC是由Microsoft开发的用于Windows操作系统的应用程序框架,它提供了许多用于开发图形用户界面的类和功能。多串口是指在一个应用程序中同时控制多个串口设备的能力。而多线程是指在一个应用程序中同时运行多个线程的能力。 在MFC中实现多串口控制涉及到串口通信的操作,可以使用MFC提供的CSerialPort类来进行串口的打开、读取和写入操作。对于多个串口设备,可以创建多个CSerialPort对象来分别控制每个串口。 而要在MFC中实现多线程,可以使用MFC提供的CWinThread类来创建和管理线程。可以通过创建多个CWinThread对象来实现多个并发运行的线程。每个线程可以执行不同的任务,通过线程间的通信和同步机制来实现数据的共享和协调。 在实现MFC多串口多线程时,可以将每个串口设备的控制逻辑分别放在不同的线程中运行,使得每个串口都可以独立地进行读取和写入操作。同时,还可以利用多线程的特性,实现同步和异步的串口通信,提高程序的效率和响应性。 总之,MFC多串口多线程的实现可以通过使用MFC提供的相关类和功能来实现。通过合理地组织和管理多个串口设备和线程,可以实现并发运行的串口通信任务,提高应用程序的灵活性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值