mfc中主线程是WinMain还是CWinThread派生的应用程序类CWinApp中的线程

如果CWinThread是主线程,它的工作函数可能是WinMain了,因为它的InitInstance()、Run()、Exitinstance()应该被它工作函数调用,... 如果CWinThread是主线程,它的工作函数可能是WinMain了,因为它的InitInstance()、Run()、Exitinstance()应该被它工作函数调用,而WinMain调用了AfxWinMain,AfxWinMain又调了前面3个函数,让人感觉它的线程工作函数是WinMain,但是WinMain是入口函数,这样他会被调用两次,一次由进程启动代码,一次由CWinThread的工作线程,请大侠分析一下到底主线程是谁。它们肯定都调用了win32的CreateThread传入了线程的工作函数,分析一下谁是主线程,如果是CWinThread,那么它的工作函数是哪个? 展开
 我来答
bhtzu
推荐于2018-01-15 · TA获得超过1.1万个赞
知道大有可为答主
回答量:8088
采纳率:85%
帮助的人:4071万
展开全部

MFC通过类、宏进行了层层封装,搞的神秘兮兮,很容易绕晕。但好在大多数功能都有源代码,只要耐心看,总可以追溯。

首先,你的提问中,CWinThread的工作函数不是WinMain,而是Run。其次,如果讨论界定在MFC的标准主线程,那么这是很明确的,同样是Run函数。

CWinApp是MFC主线程的标准类,派生后的APP类,从InitInstance进入,之后进入了CWinApp类的Run:

int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation, but has no main window!
TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
AfxPostQuitMessage(0);
}
return CWinThread::Run();
}

这里调用了基类的Run函数,实际就是启动了主工作函数CWinThread::Run,这个函数的代码如下:

int CWinThread::Run()
{
ASSERT_VALID(this);

// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;

// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
}

// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance();

// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}

} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}

ASSERT(FALSE);  // not reachable
}

在MFC程序中,AfxWinMain实际上只是起到了“承接”的作用,串联了APP类的几个函数,并不是真正的工作函数。

更多追问追答
追问
进程调createthread(_startupWinMain),WinMain是主线程工作函数此函数创建子线程传给该线程工作函数按你分析是Run可我没看到子线程创建。我认为UI线程是主线程说明CWinApp没用createthread新建线程而为线程函数WinMain提供函数,WinMain是主线程它逻辑上是CWinApp工作函数,但其实不是,而是调用了它的几个成员。不知我理解对不对
追答

我很奇怪,你说的createthread(_startupWinMain)是哪里来的?

MFC主线程的创建,实际使用的并不是API的函数CreateThread(虽然类中也有这个名字的函数),实际使用的,是C++提供的_beginthreadex函数创建的主线程,你百度一下这两个函数名,就可以知道它们的区别,不赘述了。

AfxBeginThread实际创建线程的代码是这样的:

	m_hThread = (HANDLE)_beginthreadex(lpSecurityAttrs, nStackSize,
&_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID);

从这里可以看出,你所困惑的工作函数(这应该是说法上的差异,实际上MFC的线程和API的worker线程有所不同,我认为应该理解为“线程入口地址”更合适些)其实是_AfxThreadEntry,这是一个CWinThread类的支持函数(注意,不是成员),函数中完成了CWinThread初始化并实现了主窗口和主线程的绑定。

UI线程和传统的工作者线程是不同的,不能简单的理解为“工作函数”,因为UI线程实际是在worker线程基础上加上消息循环来实现的,而传统的工作函数,退化为”入口函数“,用来标记线程入口地址,实际的线程工作,是在消息环中处理的(APP的Run函数就是做这个的)。

我认为,你是在用传统worker线程的思维去理解MFC APP这样的UI线程造成的困惑,建议多看看UI线程方面的书籍,以更好的了解两者之间的差别。

程序员黄老师
2020-05-03
知道答主
回答量:18
采纳率:0%
帮助的人:1万
展开全部

我同意你的意见,我感觉 CWinThread在MFC并未发挥创建线程的功能,仅仅是提供了几个函数比如Run给WinMain调用而已,并未产生新线程!这个里面有MFC的视频课程是这么讲解的:

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式