CWinThread 查询 (MFC)

Posted

技术标签:

【中文标题】CWinThread 查询 (MFC)【英文标题】:CWinThread Enquiries (MFC) 【发布时间】:2011-03-09 14:07:47 【问题描述】:

我有一个非常简单的问题,关于 CWinThread 的工作原理以及每次调用 ResumeThread() 时的入口点在哪里。我正在寻找一个看起来类似于“main”函数的条目,我可以在其中执行一些操作和分支。

我还想知道如何在不同线程的任何时候结束或终止正在运行的线程。我应该把 AfxEndThread() 放在哪里?还是直接调用 pThread->ExitInstance()?

我的最后一个问题是,如果我想创建多个线程,如何使用向量在标准模板库 (STL) 中组织它们?

谢谢。

【问题讨论】:

【参考方案1】:

我认为您对线程的使用方式存在根本性的误解。

SuspendThread()ResumeThread() 之类的函数以及终止线程的函数并不是您控制线程的方式。事实上,SuspendThread()ResumeThread() 映射到的 Windows API 函数被记录为用于调试器。如果 MFC 文档也这么说,那就太好了,但事实并非如此。

如果你使用SuspendThread() 来暂停一个线程,那么当你暂停它时你不知道它在做什么。如果它恰好持有一个锁,那么你可以死锁你的程序。

控制线程的正常机制是使用事件对象向线程发出信号,表明您希望它暂停或恢复。使用事件对象而不是简单的布尔标志的原因是可以等待事件。这意味着您可以将线程置于非忙碌状态,不消耗 CPU 并在控制线程发出信号时启动它。

关于终止,拨打TerminateThread()绝对是最后的手段。这样做会使您的同步对象(例如,临界区、互斥锁等)处于未定义状态,并且很可能导致您的软件出现可怕的缺陷。同样对于终止,您应该向线程发出信号,希望它退出,然后等待它退出。

【讨论】:

所以当我调用CreateThread(CREATE_SUSPENDED),启动一些东西,然后我调用ResumeThread(),线程的主要入口在哪里?我试图覆盖Run() 函数,但它不起作用。 “它不起作用”是什么意思? Run() 是入口点。我认为您应该在一个新问题中显示一些代码。【参考方案2】:

CWinThread 派生的类的主要入口点是虚拟Run() 函数。但是,还有一个 InitInstance() 函数是事前调用的,ExitInstance() 函数是事后调用的。

你永远不应该自己打电话给ExitInstance()。相反,请致电AfxEndThread,或直接从Run() 返回。

如果你真的想把你的线程放在std::vector<> 中,那么使用指针,因为类是不可复制的,当线程退出时,实例会被 MFC 自动删除。

编辑:正如 David 所指出的,您通常不想在应用程序代码中使用 SuspendThreadResumeThread。如果您使用 MFC,请以 AfxBeginThread 开头。

【讨论】:

以上是关于CWinThread 查询 (MFC)的主要内容,如果未能解决你的问题,请参考以下文章

帮助在 MFC 中使用 CWinThread

利用CWinThread实现跨线程父子MFC窗口

未调用 MFC 的 CWinThread::PostThreadMessage 处理程序

MFC_Thread

CWinThread 消息映射

MFC 线程 UI 中的帮助