vc MFC 用AfxBeginThread()启动不了线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vc MFC 用AfxBeginThread()启动不了线程相关的知识,希望对你有一定的参考价值。

开启线程中写入:
CWinThread* m_pEventThread;
m_pEventThread = AfxBeginThread(MyThread,this);
程序调试发现进入不了线程,单步调试时发现AfxBeginThread(...)函数中if条件满足,线程指针被删除了,如下:
if(!pThread->CreateThread(...))

pThread->Delete();
return NULL;

诚请高手指明为何开启不了线程???在线等,十分感谢!

CWinThread* thread;//全局变量

创建多线程:

thread=AfxBeginThread(RepThreadProc,this,THREAD_PRIORITY_NORMAL,0,0,NULL);//
RepThreadProc为//多线程函数

多线程函数:

头文件中声明:

static UINT RepThreadProc(LPVOID
pParam);

源文件中定义:

UINT
CRepeat::RepThreadProc(LPVOIDpParam)// CRepeat为使用多线程的类


while(XXX)//条件判断是否退出多线程,XXX自己定义变量来控制


//在这实现多线程代码


return 0;

参考技术A 调试的时候,在Watch(监视)里面添加一个“@err”,然后到你那个如下的地方的时候,光标停在pThread->Delete处,看那个@err是什么数字。然后到msdn上找system error codes,看看数字对应的是什么错误 参考技术B 看看你的MyThread函数,是不是一进线程就退出线程了追问

没有,是AfxBeginThread()函数中
if(!pThread->CreateThread(...))

pThread->Delete();
return NULL;

的问题,但是这个是我调用的,不知道怎么会跳到if中执行pThread->Delete();

追答

不要看AfxBeginThread是怎么执行的。。去看你的MyThread函数,那才是你线程要执行的函数

追问

由于pThread->Delete(); 所以程序根本跳不到MyThread()函数

追答

线程创建失败了,在AfxBeginThread后面加上一句

DWORD dwErr = GetLastError();
看看错误码是多少?

追问

错误码=0

追答

这么奇怪。。我想看看你的MyThread的函数声明可以吗?
线程函数必须是全局函数或者静态成员函数
且必须是__stdcall调用约定
MFC的AfxBeginThread的线程函数可以写为
UINT MyThread(LPVOID pParam);

追问

就是这个
UINT MyThread(LPVOID pParam);

追答

刚刚说错了应该是__cdecl调用约定
你的这个函数是全局函数吗?
如果是类的成员函数要定义为静态函数
另外需要设置运行库为多线程的

不过你这里既然能编译通过,应该不是代码语法问题,不知道你的具体情况
GetLastError返回0说明是执行正常的,你是不是用的Release版本再调试啊。。

参考技术C 把LastError查询出来追问

谢谢!如何查LastError?

追答

在出错的代码之后 调用 GetLastError
看看返回值

追问

返回值为0

追答

没有错误的话 那么你的MyThread函数是否设置了死循环 如果没有 在里面加上试试

while (1)

Sleep(1);

追问

MyThread()函数肯定没有问题,而且目前还没有执行到该函数,是AfxBeginThread()函数中
if(!pThread->CreateThread(...))的问题,但是这个是我调用的,不知道怎么会跳到if中执行pThread->Delete();
我的程序在开启这个线程之前有串口通信,我怀疑跟这个有关,所以将串口关闭,但是还是进不了线程

追答

那就不知道了 贴全一点代码看看?

MFC 和 AfxBeginThread 的线程调度问题

【中文标题】MFC 和 AfxBeginThread 的线程调度问题【英文标题】:Thread scheduling issue with MFC and AfxBeginThread 【发布时间】:2011-08-21 21:04:11 【问题描述】:

我正在使用 AfxBeginThread 在 MFC 中创建一个工作线程,但该线程没有被调度。代码如下:

CWinThread* worker = AfxBeginThread(initialUpdateWorkerThread, this);
DWORD dwExitCode = 0;
while(GetExitCodeThread(worker->m_hThread, &dwExitCode))

    if(dwExitCode != STILL_ACTIVE)
        break;
    ::Sleep(100);

当我运行它时,这个循环只是活锁,因为从不调用 initialUpdateWorkerThread(我在它的顶部放置了断点和消息框)所以 dwExitCode 总是 STILL_ACITVE。但是,如果我在循环之前但在 AfxBeginThread 之后调用 AfxMessageBox,则调用该函数。这让我觉得我没有调用正确的函数来安排线程,但是调用 AfxMessageBox 会导致它被安排。

如何强制调度线程?我认为 sleep 会这样做,但在这种情况下似乎不会。

【问题讨论】:

奇怪。您正在以最简单的方式使用 AfxBeginThread,因此它显然应该可以正常工作。那是您正在运行的确切代码,还是您传递的是其他一些参数?此外,在while 之前放置一个断点会很有趣,并查看新线程挂起的位置。 我不买。但是,您的等待循环完全无聊,它假定 SILL_EXECUTING 在忙碌时返回。没有检查它甚至开始了。您必须使用 WaitForSingleObject(worker->m_hThread) 来检测何时完成。也不需要讨厌的等待循环。 我也尝试过使用 WaitForSingleObject,但效果不佳(如果我设置了时间限制,它只会挂起或超时)。如何检查线程是否已启动?这也是我正在运行的确切代码;我从我的源文件中复制粘贴了它。 【参考方案1】:

您的工作线程可能正在尝试向您的主线程发送消息,但由于您没有在主线程上处理消息,因此工作线程只是等待。您可以通过简单地闯入调试器以查看工作线程在做什么来确认这一点。

【讨论】:

是的,你完全正确。我正在调用“((CMainFrame *)AfxGetApp()->m_pMainWnd)->EnableWindow(FALSE);”在工作函数的最顶部,我一直将断点放在较低的位置(顶部有一堆变量声明,我没有注意到其中的实际调用)。在我调用“DoMsgTranslations()”之后,它只是遍历所有消息并处理它们,在主线程中,我的工作线程现在运行。感谢您的帮助。

以上是关于vc MFC 用AfxBeginThread()启动不了线程的主要内容,如果未能解决你的问题,请参考以下文章

MFC 和 AfxBeginThread 的线程调度问题

MFC 多线程:AfxBeginThread 与 Boost.Thread?

使用MFC中的AfxBeginThread创建多线程

猎豹MFC--进程和线程--创建线程AfxBeginThread() SetDlgItemInt()线程暂停继续终止

VC 在子线程中结束主窗口程序

如何使用 AfxBeginThread创建MFC线程对象和Win32线程对象