CWinThread 查询 (MFC)
我有一个非常简单的问题,关于 CWinThread 如何工作以及每次调用 ResumeThread() 时入口点在哪里。我正在寻找一个看起来类似于“main”函数的条目,我可以在其中执行一些操作和分支。
我还想知道如何在不同线程的任何时候结束或终止正在运行的线程。我应该把 AfxEndThread() 放在哪里?或者简单地调用 pThread->ExitInstance()?
我的最后一个问题是,如果我想创建多个线程,如何使用向量在标准模板库(STL)中组织它们?
谢谢。
I have a very simple question about how CWinThread works and where is the entry point everytime I called ResumeThread(). I'm looking for an entry that looks similar as "main" function where I can perform some operations and branches.
I'm also wondering how to end or kill running threads at any point from different thread. Where should I put AfxEndThread()? or simply call pThread->ExitInstance()?
My last question is, if i want to make multiple threads, how do I organize them in Standard Template Library (STL) using vector?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您对如何使用线程有一个根本性的误解。
SuspendThread()
和ResumeThread()
等函数以及终止线程的函数并不是控制线程的方式。事实上,SuspendThread()
和ResumeThread()
映射到的 Windows API 函数被记录为供调试器使用。如果 MFC 文档也这么说就好了,但事实并非如此。如果您使用
SuspendThread()
来暂停线程,那么当您暂停它时您不知道它在做什么。如果它恰好持有锁,那么您的程序可能会死锁。控制线程的正常机制是使用事件对象向线程发出信号,表明您希望其暂停或恢复。使用事件对象而不是简单的布尔标志的原因是,可以等待事件。这意味着您可以将线程置于非繁忙状态,不消耗 CPU,并在控制线程发出信号时启动它。
关于终止,调用
TerminateThread()
绝对是最后的手段。这样做会使您的同步对象(例如关键部分、互斥体等)处于未定义状态,并且很可能导致软件中出现可怕的缺陷。同样,对于终止,您应该向线程发出信号,表示您希望它退出,然后等待它退出。I think you have a fundamental misunderstanding of how threads are meant to be used.
Functions like
SuspendThread()
andResumeThread()
and functions to terminate threads are not how you are meant to control threads. In fact, the Windows API functions thatSuspendThread()
andResumeThread()
map onto are documented as being intended for debuggers. It would be nice if the MFC documentation also said this, but it doesn't.If you use
SuspendThread()
to pause a thread then you've no idea what it is doing when you pause it. If it just happens to hold a lock then you can deadlock your program.The normal mechanism for controlling threads is to use event objects to signal to the thread that you want it to pause or resume. The reason event objects are used rather than simple boolean flags, say, is that events can be waited on. This means that you can put a thread into a non-busy state, not consume CPU and have it start-up when signalled by the controlling thread.
Regarding termination, it is absolutely a last resort to call
TerminateThread()
. Doing so leaves your synchronisation objects (e.g. critical sections, mutexes etc.) in an undefined state and is highly likely to lead to horrible defects in your software. Again for termination you should signal to a thread that you wish it to quit, and then wait until it has done so.从
CWinThread
派生的类的主要入口点是虚拟Run()
函数。不过,还有一个事先调用的InitInstance()
函数,以及随后调用的ExitInstance()
函数。您永远不应该自己调用
ExitInstance()
。相反,调用AfxEndThread
,或者直接从Run()
返回。如果您确实想将线程放入
std::vector
中,请使用指针,因为该类不可复制,并且当线程退出时,MFC 会自动删除该实例。编辑:正如 David 指出的,您通常不想在应用程序代码中使用
SuspendThread
和ResumeThread
。如果您使用的是 MFC,请使用AfxBeginThread
启动线程。The primary entry point for a class derived from
CWinThread
is the virtualRun()
function. However, there is also anInitInstance()
function which is called beforehand, and anExitInstance()
function called afterwards.You should never call
ExitInstance()
yourself. Instead, callAfxEndThread
, or just return fromRun()
.If you really want to put your threads in a
std::vector<>
then use a pointer as the class is not copyable, and the instance is deleted automatically by MFC when the thread exits.Edit: As David pointed out, you generally don't want to use
SuspendThread
andResumeThread
in application code. Start your thread withAfxBeginThread
if you're using MFC.