鱼C论坛

 找回密码
 立即注册
查看: 2523|回复: 2

[已解决]C++ MFC框架下的多线程问题

[复制链接]
发表于 2021-5-7 22:36:52 | 显示全部楼层 |阅读模式
60鱼币
我目前在学习用C++ MFC框架编写坦克大战程序,老师要求我们使用多线程来进行坦克与墙的碰撞测试。
老师给出的提示是使用thread模块,然后使用std::thread t(函数名,参数);  
这样做在普通的C++程序中能实现,但是在MFC框架下就一直报错
所以有没有有经验的大佬给我讲解一下MFC框架下想要使用一个多线程应该怎么使用(给一个例子就行,我主要想知道声明和调用多线程函数在哪写不会报错)
最佳答案
2021-5-7 22:36:53
本帖最后由 xieglt 于 2021-5-8 11:04 编辑

CommonThread.H
  1. #ifndef        H_COMMON_THREAD
  2. #define        H_COMMON_THREAD

  3. #include <windows.h>        //mfc 下不需要包含此头文件
  4. #include <process.h>

  5. class CCommonThread  
  6. {
  7. public:
  8.         CCommonThread();
  9.         virtual ~CCommonThread();

  10. private:
  11.         CCommonThread(const CCommonThread &);
  12.         operator = (const CCommonThread &);

  13. protected:
  14.         BOOL        m_bRun;
  15.         HANDLE        m_hThread;
  16.         HANDLE        m_hExit;

  17. private:       
  18.         static unsigned int WINAPI        ThreadFunction(LPVOID lParam);

  19. protected:
  20.         BOOL        WaitForExit(DWORD dwTime = 50);
  21.         void        ExitInsideLoop()
  22.                 {
  23.                         SetEvent(m_hExit);
  24.                 }

  25. protected:
  26.         virtual unsigned int ThreadBody();

  27. public:
  28.         BOOL        BeginThread();
  29.         void        EndThread(UINT nWaitTime = 1000);
  30.        
  31. };

  32. #endif
复制代码


CommonThread.CPP

  1. #include "stdafx.h"
  2. #include "CommonThread.h"


  3. CCommonThread::CCommonThread()
  4. {
  5.         m_bRun = FALSE;
  6.         m_hThread = NULL;
  7.         m_hExit = NULL;
  8. }

  9. CCommonThread::~CCommonThread()
  10. {
  11.         if(m_hExit != NULL)
  12.         {
  13.                 CloseHandle(m_hExit);
  14.                 m_hExit = NULL;
  15.         }

  16.         EndThread();
  17. }

  18. BOOL CCommonThread::WaitForExit(DWORD dwTime)
  19. {
  20.         DWORD dwRet = WaitForSingleObject(m_hExit,dwTime);
  21.        
  22.         if(dwRet == WAIT_TIMEOUT)
  23.         {
  24.                 return FALSE;
  25.         }
  26.         else
  27.         {
  28.                 ResetEvent(m_hExit);
  29.                 return TRUE;
  30.         }
  31. }

  32. unsigned int  WINAPI CCommonThread::ThreadFunction(LPVOID lParam)
  33. {
  34.         unsigned int  nRet = 0;

  35.         CCommonThread * lpThread = reinterpret_cast<CCommonThread *>(lParam);

  36.         nRet = lpThread->ThreadBody();
  37.        
  38.         lpThread->m_bRun = FALSE;

  39.         return nRet;
  40. }

  41. unsigned int CCommonThread::ThreadBody()
  42. {       
  43.         return 0;
  44. }

  45. BOOL CCommonThread::BeginThread()
  46. {
  47.         do
  48.         {
  49.                 if(m_bRun)
  50.                 {
  51.                         break;
  52.                 }
  53.                
  54.                 if(m_hExit == NULL)
  55.                 {
  56.                         m_hExit = ::CreateEvent(NULL,FALSE,FALSE,NULL);
  57.                         if(m_hExit == NULL)
  58.                         {
  59.                                 break;
  60.                         }
  61.                 }
  62.                 else
  63.                 {
  64.                         ResetEvent(m_hExit);
  65.                 }
  66.                
  67.                 unsigned int dwThreadID = 0;
  68.                 m_hThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL,0,ThreadFunction,this,0,&dwThreadID));

  69.                 if(m_hThread == NULL)
  70.                 {
  71.                         break;
  72.                 }

  73.                 m_bRun = TRUE;
  74.         }while(FALSE);

  75.         return m_bRun;
  76. }


  77. void CCommonThread::EndThread(UINT nWaitTime)
  78. {
  79.         if(m_bRun)
  80.         {
  81.                 SetEvent(m_hExit);
  82.                
  83.                 if(WaitForSingleObject(m_hThread,nWaitTime) == WAIT_TIMEOUT)
  84.                 {
  85.                         _endthreadex(reinterpret_cast<unsigned int>(m_hThread));
  86.                 }
  87.                
  88.                 CloseHandle(m_hThread);
  89.                 m_hThread = NULL;
  90.                 m_bRun = FALSE;
  91.         }
  92. }
复制代码


main.c

  1. #include "stdafx.h"
  2. #include "CommonThread.H"
  3. #include <stdio.h>

  4. class ThreadTest : public CCommonThread
  5. {
  6. public:
  7.         ThreadTest(int i=1)
  8.         {
  9.                 _begin = i;
  10.         }
  11. private:
  12.         unsigned int ThreadBody()
  13.         {
  14.                 for(int i = _begin ; i <= 100 ; i+=2)
  15.                 {
  16.                         printf("T%d:%d\t",_begin,i);

  17.                         if(WaitForExit())
  18.                         {
  19.                                 break;
  20.                         }
  21.                 }
  22.                 return 0;
  23.         }

  24. private:
  25.         int _begin;
  26. };


  27. int main(int argc, char* argv[])
  28. {
  29.         ThreadTest tt1(1);
  30.         ThreadTest tt2(2);
  31.         tt1.BeginThread();
  32.         tt2.BeginThread();

  33.         getchar();

  34.         tt1.EndThread();
  35.         tt2.EndThread();
  36.         return 0;
  37. }
复制代码


未命名.JPG

最佳答案

查看完整内容

CommonThread.H CommonThread.CPP main.c
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-5-7 22:36:53 | 显示全部楼层    本楼为最佳答案   
本帖最后由 xieglt 于 2021-5-8 11:04 编辑

CommonThread.H
  1. #ifndef        H_COMMON_THREAD
  2. #define        H_COMMON_THREAD

  3. #include <windows.h>        //mfc 下不需要包含此头文件
  4. #include <process.h>

  5. class CCommonThread  
  6. {
  7. public:
  8.         CCommonThread();
  9.         virtual ~CCommonThread();

  10. private:
  11.         CCommonThread(const CCommonThread &);
  12.         operator = (const CCommonThread &);

  13. protected:
  14.         BOOL        m_bRun;
  15.         HANDLE        m_hThread;
  16.         HANDLE        m_hExit;

  17. private:       
  18.         static unsigned int WINAPI        ThreadFunction(LPVOID lParam);

  19. protected:
  20.         BOOL        WaitForExit(DWORD dwTime = 50);
  21.         void        ExitInsideLoop()
  22.                 {
  23.                         SetEvent(m_hExit);
  24.                 }

  25. protected:
  26.         virtual unsigned int ThreadBody();

  27. public:
  28.         BOOL        BeginThread();
  29.         void        EndThread(UINT nWaitTime = 1000);
  30.        
  31. };

  32. #endif
复制代码


CommonThread.CPP

  1. #include "stdafx.h"
  2. #include "CommonThread.h"


  3. CCommonThread::CCommonThread()
  4. {
  5.         m_bRun = FALSE;
  6.         m_hThread = NULL;
  7.         m_hExit = NULL;
  8. }

  9. CCommonThread::~CCommonThread()
  10. {
  11.         if(m_hExit != NULL)
  12.         {
  13.                 CloseHandle(m_hExit);
  14.                 m_hExit = NULL;
  15.         }

  16.         EndThread();
  17. }

  18. BOOL CCommonThread::WaitForExit(DWORD dwTime)
  19. {
  20.         DWORD dwRet = WaitForSingleObject(m_hExit,dwTime);
  21.        
  22.         if(dwRet == WAIT_TIMEOUT)
  23.         {
  24.                 return FALSE;
  25.         }
  26.         else
  27.         {
  28.                 ResetEvent(m_hExit);
  29.                 return TRUE;
  30.         }
  31. }

  32. unsigned int  WINAPI CCommonThread::ThreadFunction(LPVOID lParam)
  33. {
  34.         unsigned int  nRet = 0;

  35.         CCommonThread * lpThread = reinterpret_cast<CCommonThread *>(lParam);

  36.         nRet = lpThread->ThreadBody();
  37.        
  38.         lpThread->m_bRun = FALSE;

  39.         return nRet;
  40. }

  41. unsigned int CCommonThread::ThreadBody()
  42. {       
  43.         return 0;
  44. }

  45. BOOL CCommonThread::BeginThread()
  46. {
  47.         do
  48.         {
  49.                 if(m_bRun)
  50.                 {
  51.                         break;
  52.                 }
  53.                
  54.                 if(m_hExit == NULL)
  55.                 {
  56.                         m_hExit = ::CreateEvent(NULL,FALSE,FALSE,NULL);
  57.                         if(m_hExit == NULL)
  58.                         {
  59.                                 break;
  60.                         }
  61.                 }
  62.                 else
  63.                 {
  64.                         ResetEvent(m_hExit);
  65.                 }
  66.                
  67.                 unsigned int dwThreadID = 0;
  68.                 m_hThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL,0,ThreadFunction,this,0,&dwThreadID));

  69.                 if(m_hThread == NULL)
  70.                 {
  71.                         break;
  72.                 }

  73.                 m_bRun = TRUE;
  74.         }while(FALSE);

  75.         return m_bRun;
  76. }


  77. void CCommonThread::EndThread(UINT nWaitTime)
  78. {
  79.         if(m_bRun)
  80.         {
  81.                 SetEvent(m_hExit);
  82.                
  83.                 if(WaitForSingleObject(m_hThread,nWaitTime) == WAIT_TIMEOUT)
  84.                 {
  85.                         _endthreadex(reinterpret_cast<unsigned int>(m_hThread));
  86.                 }
  87.                
  88.                 CloseHandle(m_hThread);
  89.                 m_hThread = NULL;
  90.                 m_bRun = FALSE;
  91.         }
  92. }
复制代码


main.c

  1. #include "stdafx.h"
  2. #include "CommonThread.H"
  3. #include <stdio.h>

  4. class ThreadTest : public CCommonThread
  5. {
  6. public:
  7.         ThreadTest(int i=1)
  8.         {
  9.                 _begin = i;
  10.         }
  11. private:
  12.         unsigned int ThreadBody()
  13.         {
  14.                 for(int i = _begin ; i <= 100 ; i+=2)
  15.                 {
  16.                         printf("T%d:%d\t",_begin,i);

  17.                         if(WaitForExit())
  18.                         {
  19.                                 break;
  20.                         }
  21.                 }
  22.                 return 0;
  23.         }

  24. private:
  25.         int _begin;
  26. };


  27. int main(int argc, char* argv[])
  28. {
  29.         ThreadTest tt1(1);
  30.         ThreadTest tt2(2);
  31.         tt1.BeginThread();
  32.         tt2.BeginThread();

  33.         getchar();

  34.         tt1.EndThread();
  35.         tt2.EndThread();
  36.         return 0;
  37. }
复制代码


未命名.JPG
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-5-7 22:56:39 | 显示全部楼层
thread要用类方法的话必须是静态方法

评分

参与人数 1鱼币 +5 收起 理由
King丨小义 + 5

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-29 10:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表