MFC创建界面线程时测试提示内存不足

时间:2023-01-20 18:15:25
如题,用网上如下方法创建界面线程,在vs2005中编译调试,界面没有显示,直接提示内存不足,但是实际内存空闲很多,请问这是怎么回事?
创建方法如下:
1.创建MFC对话框程序,添加一个启动用户界面线程的按钮
2.向程序中添加一个对话框,并建立相应的对话框类CThreadDlg,该对话框将被作为用户界面线程的主窗口。
3.向程序中添加一个以CWinThread为基类的新类CUIThread,该类用于启动一个用户界面线程。
4.在UIThread.cpp中加入#include "ThreadDlg.h",并在CUIThread::InitInstance()中加入
  CThreadDlg dlg;
  m_pMainWnd=&dlg;
  dlg.DoModal();
  确保InitInstance函数最后return TRUE;
5.CMyThread::InitInstance()中创建的CThreadDlg将与主窗口在独立的线程中运行,可以在CThreadDlg中加入各种执行耗时任务的代码而不会影响主窗口的运行。
6.在主窗口的**dlg.h加入#include "UIThread.h",双击按钮添加CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));开启线程。
等解释



8 个解决方案

#1


线程中是不是占用堆内存超过4MB?

#2


引用 1 楼  的回复:
线程中是不是占用堆内存超过4MB?

这个怎么查看啊?不太清楚。。。

#3


大约计算下吧。
-
以前好像在那本书里看到的。
上面说错了。
单个函数栈内存使用超过4MB,会导致程序崩溃。


引用 2 楼  的回复:
引用 1 楼  的回复:
线程中是不是占用堆内存超过4MB?

这个怎么查看啊?不太清楚。。。

#4


引用 3 楼  的回复:
大约计算下吧。
-
以前好像在那本书里看到的。
上面说错了。
单个函数栈内存使用超过4MB,会导致程序崩溃。


引用 2 楼  的回复:

引用 1 楼  的回复:
线程中是不是占用堆内存超过4MB?

这个怎么查看啊?不太清楚。。。
为什么孙鑫的视频里说是4GB

#5


如果是一运行就内存不足了,一般不是堆内存用完了,而是栈内存用完了。
而栈内存用完一般是因为有几个函数相互调用,导致递而不归的现象,一下子出来几百万层的堆栈,把栈空间用完了。
可以从这方面找下原因。
也有可能是在某个函数中一下子在栈上面分配了大量的内存,也会导致栈溢出。比如
char buff[1024*1024*1024]这种。

#6


遇到同样问题,   不过应该不是真正内存不足。 还在找原因。

CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));
这句 换成:

CUIThread* pThread=new CUIThread();
pThread->CreateThread();

就可以了, 还没想通为什么出错。

#7


第6步,这句CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));是不是应该改成
CUIThread  *pThread=(CUIThread  *)AfxBeginThread(RUNTIME_CLASS(CUIThread));我没有试过。但是最近也在看这方面的 例子。
创建用户界面线程有两种方法:(这是我自己的例子)
使用AfxBeginThread创建用户界面线程 过程。
1、用户需要自己创建一个CWinThread的一个派生类。在创建类时选择基类为CWinThread.
2、定义线程指针并启动线程。
一般情况下,推荐使用AfxBeginThread()来一次性地创建并启动一个线程,如写如下代码:
CUIPolingThread* UIThread=(CUIPolingThread*)AfxBeginThread(RUNTIME_CLASS(CUIPolingThread),0,CREATE_SUSPENDED,NULL);
其中AfxBeginThread函数各个参数参照MSDN.

法二:但是也可以通过两步法来创建线程:首先创建CWinThread类的一个对象,然后调用该对象的成员函数CreateThread()来启动该线程。
也可以这样操作:
UIThread=new CUIPolingThread();  //已经参照程序修改为下一句
 UIThread->CreateThread(CREATE_SUSPENDED);//挂起线程
//在需要启动线程的地方写下面的函数
UIThread->ResumeThread();//启动线程
所以6楼的哥们是用的第二种方法。

#8


CreateThread是一个Windows的API函数,而AfxBeginThread则是MFC中的线程创建函数,也是个CWinThread的全局函数,在调用这两种不同的函数的,系统的运行机制也是不一样的,所以
把CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));
这句 换成:
CUIThread* pThread=new CUIThread();
pThread->CreateThread();           是不等价的。
这两个指针一个是CWinThread ,一个是CUIThread,虽然是继承的关系,但是函数AfxBeginThread是CWinThread ,作为window系统的线程大基类,使用应该和window系统去抢占资源了,当然了应该还可结构体RUNTIME_CLASS是一有关系,具体的我也说不好,大createThread知识一个API啦,这是我这么觉得啦。

地方出错的在wincore.cpp捕获异常处,高手可以详解一下:

TRY
{
#ifndef _AFX_NO_OCC_SUPPORT
// special case for WM_DESTROY
if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))
pWnd->m_pCtrlCont->OnUIActivate(NULL);
#endif

// special case for WM_INITDIALOG
CRect rectOld;
DWORD dwStyle = 0;
if (nMsg == WM_INITDIALOG)
_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);

// delegate to object's WindowProc
lResult = pWnd->WindowProc(nMsg, wParam, lParam);

// more special case for WM_INITDIALOG
if (nMsg == WM_INITDIALOG)
_AfxPostInitDialog(pWnd, rectOld, dwStyle);
}
CATCH_ALL(e)
{
lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg);
TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n",
lResult);
DELETE_EXCEPTION(e);
}

#1


线程中是不是占用堆内存超过4MB?

#2


引用 1 楼  的回复:
线程中是不是占用堆内存超过4MB?

这个怎么查看啊?不太清楚。。。

#3


大约计算下吧。
-
以前好像在那本书里看到的。
上面说错了。
单个函数栈内存使用超过4MB,会导致程序崩溃。


引用 2 楼  的回复:
引用 1 楼  的回复:
线程中是不是占用堆内存超过4MB?

这个怎么查看啊?不太清楚。。。

#4


引用 3 楼  的回复:
大约计算下吧。
-
以前好像在那本书里看到的。
上面说错了。
单个函数栈内存使用超过4MB,会导致程序崩溃。


引用 2 楼  的回复:

引用 1 楼  的回复:
线程中是不是占用堆内存超过4MB?

这个怎么查看啊?不太清楚。。。
为什么孙鑫的视频里说是4GB

#5


如果是一运行就内存不足了,一般不是堆内存用完了,而是栈内存用完了。
而栈内存用完一般是因为有几个函数相互调用,导致递而不归的现象,一下子出来几百万层的堆栈,把栈空间用完了。
可以从这方面找下原因。
也有可能是在某个函数中一下子在栈上面分配了大量的内存,也会导致栈溢出。比如
char buff[1024*1024*1024]这种。

#6


遇到同样问题,   不过应该不是真正内存不足。 还在找原因。

CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));
这句 换成:

CUIThread* pThread=new CUIThread();
pThread->CreateThread();

就可以了, 还没想通为什么出错。

#7


第6步,这句CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));是不是应该改成
CUIThread  *pThread=(CUIThread  *)AfxBeginThread(RUNTIME_CLASS(CUIThread));我没有试过。但是最近也在看这方面的 例子。
创建用户界面线程有两种方法:(这是我自己的例子)
使用AfxBeginThread创建用户界面线程 过程。
1、用户需要自己创建一个CWinThread的一个派生类。在创建类时选择基类为CWinThread.
2、定义线程指针并启动线程。
一般情况下,推荐使用AfxBeginThread()来一次性地创建并启动一个线程,如写如下代码:
CUIPolingThread* UIThread=(CUIPolingThread*)AfxBeginThread(RUNTIME_CLASS(CUIPolingThread),0,CREATE_SUSPENDED,NULL);
其中AfxBeginThread函数各个参数参照MSDN.

法二:但是也可以通过两步法来创建线程:首先创建CWinThread类的一个对象,然后调用该对象的成员函数CreateThread()来启动该线程。
也可以这样操作:
UIThread=new CUIPolingThread();  //已经参照程序修改为下一句
 UIThread->CreateThread(CREATE_SUSPENDED);//挂起线程
//在需要启动线程的地方写下面的函数
UIThread->ResumeThread();//启动线程
所以6楼的哥们是用的第二种方法。

#8


CreateThread是一个Windows的API函数,而AfxBeginThread则是MFC中的线程创建函数,也是个CWinThread的全局函数,在调用这两种不同的函数的,系统的运行机制也是不一样的,所以
把CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));
这句 换成:
CUIThread* pThread=new CUIThread();
pThread->CreateThread();           是不等价的。
这两个指针一个是CWinThread ,一个是CUIThread,虽然是继承的关系,但是函数AfxBeginThread是CWinThread ,作为window系统的线程大基类,使用应该和window系统去抢占资源了,当然了应该还可结构体RUNTIME_CLASS是一有关系,具体的我也说不好,大createThread知识一个API啦,这是我这么觉得啦。

地方出错的在wincore.cpp捕获异常处,高手可以详解一下:

TRY
{
#ifndef _AFX_NO_OCC_SUPPORT
// special case for WM_DESTROY
if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))
pWnd->m_pCtrlCont->OnUIActivate(NULL);
#endif

// special case for WM_INITDIALOG
CRect rectOld;
DWORD dwStyle = 0;
if (nMsg == WM_INITDIALOG)
_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);

// delegate to object's WindowProc
lResult = pWnd->WindowProc(nMsg, wParam, lParam);

// more special case for WM_INITDIALOG
if (nMsg == WM_INITDIALOG)
_AfxPostInitDialog(pWnd, rectOld, dwStyle);
}
CATCH_ALL(e)
{
lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg);
TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n",
lResult);
DELETE_EXCEPTION(e);
}