鱼C论坛

 找回密码
 立即注册
查看: 2200|回复: 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
#ifndef        H_COMMON_THREAD
#define        H_COMMON_THREAD

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

class CCommonThread  
{
public:
        CCommonThread();
        virtual ~CCommonThread();

private:
        CCommonThread(const CCommonThread &);
        operator = (const CCommonThread &);

protected:
        BOOL        m_bRun;
        HANDLE        m_hThread;
        HANDLE        m_hExit;

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

protected:
        BOOL        WaitForExit(DWORD dwTime = 50);
        void        ExitInsideLoop()
                {
                        SetEvent(m_hExit);
                }

protected:
        virtual unsigned int ThreadBody();

public:
        BOOL        BeginThread();
        void        EndThread(UINT nWaitTime = 1000);
        
};

#endif

CommonThread.CPP
#include "stdafx.h"
#include "CommonThread.h"


CCommonThread::CCommonThread()
{
        m_bRun = FALSE;
        m_hThread = NULL;
        m_hExit = NULL;
}

CCommonThread::~CCommonThread()
{
        if(m_hExit != NULL)
        {
                CloseHandle(m_hExit);
                m_hExit = NULL;
        }

        EndThread();
}

BOOL CCommonThread::WaitForExit(DWORD dwTime)
{
        DWORD dwRet = WaitForSingleObject(m_hExit,dwTime);
        
        if(dwRet == WAIT_TIMEOUT)
        {
                return FALSE;
        }
        else
        {
                ResetEvent(m_hExit);
                return TRUE;
        }
}

unsigned int  WINAPI CCommonThread::ThreadFunction(LPVOID lParam)
{
        unsigned int  nRet = 0;

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

        nRet = lpThread->ThreadBody();
        
        lpThread->m_bRun = FALSE;

        return nRet;
}

unsigned int CCommonThread::ThreadBody()
{        
        return 0;
}

BOOL CCommonThread::BeginThread()
{
        do 
        {
                if(m_bRun)
                {
                        break;
                }
                
                if(m_hExit == NULL)
                {
                        m_hExit = ::CreateEvent(NULL,FALSE,FALSE,NULL);
                        if(m_hExit == NULL)
                        {
                                break;
                        }
                }
                else
                {
                        ResetEvent(m_hExit);
                }
                
                unsigned int dwThreadID = 0;
                m_hThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL,0,ThreadFunction,this,0,&dwThreadID));

                if(m_hThread == NULL)
                {
                        break;
                }

                m_bRun = TRUE;
        }while(FALSE);

        return m_bRun;
}


void CCommonThread::EndThread(UINT nWaitTime)
{
        if(m_bRun)
        {
                SetEvent(m_hExit);
                
                if(WaitForSingleObject(m_hThread,nWaitTime) == WAIT_TIMEOUT)
                {
                        _endthreadex(reinterpret_cast<unsigned int>(m_hThread));
                }
                
                CloseHandle(m_hThread);
                m_hThread = NULL;
                m_bRun = FALSE;
        }
}

main.c
#include "stdafx.h"
#include "CommonThread.H"
#include <stdio.h>

class ThreadTest : public CCommonThread
{
public:
        ThreadTest(int i=1)
        {
                _begin = i;
        }
private:
        unsigned int ThreadBody()
        {
                for(int i = _begin ; i <= 100 ; i+=2)
                {
                        printf("T%d:%d\t",_begin,i);

                        if(WaitForExit())
                        {
                                break;
                        }
                }
                return 0;
        }

private:
        int _begin;
};


int main(int argc, char* argv[])
{
        ThreadTest tt1(1);
        ThreadTest tt2(2);
        tt1.BeginThread();
        tt2.BeginThread();

        getchar();

        tt1.EndThread();
        tt2.EndThread();
        return 0;
}

未命名.JPG

最佳答案

查看完整内容

CommonThread.H CommonThread.CPP main.c
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

CommonThread.H
#ifndef        H_COMMON_THREAD
#define        H_COMMON_THREAD

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

class CCommonThread  
{
public:
        CCommonThread();
        virtual ~CCommonThread();

private:
        CCommonThread(const CCommonThread &);
        operator = (const CCommonThread &);

protected:
        BOOL        m_bRun;
        HANDLE        m_hThread;
        HANDLE        m_hExit;

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

protected:
        BOOL        WaitForExit(DWORD dwTime = 50);
        void        ExitInsideLoop()
                {
                        SetEvent(m_hExit);
                }

protected:
        virtual unsigned int ThreadBody();

public:
        BOOL        BeginThread();
        void        EndThread(UINT nWaitTime = 1000);
        
};

#endif

CommonThread.CPP
#include "stdafx.h"
#include "CommonThread.h"


CCommonThread::CCommonThread()
{
        m_bRun = FALSE;
        m_hThread = NULL;
        m_hExit = NULL;
}

CCommonThread::~CCommonThread()
{
        if(m_hExit != NULL)
        {
                CloseHandle(m_hExit);
                m_hExit = NULL;
        }

        EndThread();
}

BOOL CCommonThread::WaitForExit(DWORD dwTime)
{
        DWORD dwRet = WaitForSingleObject(m_hExit,dwTime);
        
        if(dwRet == WAIT_TIMEOUT)
        {
                return FALSE;
        }
        else
        {
                ResetEvent(m_hExit);
                return TRUE;
        }
}

unsigned int  WINAPI CCommonThread::ThreadFunction(LPVOID lParam)
{
        unsigned int  nRet = 0;

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

        nRet = lpThread->ThreadBody();
        
        lpThread->m_bRun = FALSE;

        return nRet;
}

unsigned int CCommonThread::ThreadBody()
{        
        return 0;
}

BOOL CCommonThread::BeginThread()
{
        do 
        {
                if(m_bRun)
                {
                        break;
                }
                
                if(m_hExit == NULL)
                {
                        m_hExit = ::CreateEvent(NULL,FALSE,FALSE,NULL);
                        if(m_hExit == NULL)
                        {
                                break;
                        }
                }
                else
                {
                        ResetEvent(m_hExit);
                }
                
                unsigned int dwThreadID = 0;
                m_hThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL,0,ThreadFunction,this,0,&dwThreadID));

                if(m_hThread == NULL)
                {
                        break;
                }

                m_bRun = TRUE;
        }while(FALSE);

        return m_bRun;
}


void CCommonThread::EndThread(UINT nWaitTime)
{
        if(m_bRun)
        {
                SetEvent(m_hExit);
                
                if(WaitForSingleObject(m_hThread,nWaitTime) == WAIT_TIMEOUT)
                {
                        _endthreadex(reinterpret_cast<unsigned int>(m_hThread));
                }
                
                CloseHandle(m_hThread);
                m_hThread = NULL;
                m_bRun = FALSE;
        }
}

main.c
#include "stdafx.h"
#include "CommonThread.H"
#include <stdio.h>

class ThreadTest : public CCommonThread
{
public:
        ThreadTest(int i=1)
        {
                _begin = i;
        }
private:
        unsigned int ThreadBody()
        {
                for(int i = _begin ; i <= 100 ; i+=2)
                {
                        printf("T%d:%d\t",_begin,i);

                        if(WaitForExit())
                        {
                                break;
                        }
                }
                return 0;
        }

private:
        int _begin;
};


int main(int argc, char* argv[])
{
        ThreadTest tt1(1);
        ThreadTest tt2(2);
        tt1.BeginThread();
        tt2.BeginThread();

        getchar();

        tt1.EndThread();
        tt2.EndThread();
        return 0;
}

未命名.JPG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 11:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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