假设我有一个阻塞方法,让我们在Block()中调用。
由于我不希望我的主线程阻塞,我可能会创建一个工作线程,相反,它将调用Block。
不过,我还有另外一个条件。
我希望调用阻止在5秒内返回顶部,否则,我想让主线程知道对块的调用失败,并退出工作线程。
对于这种情况,什么才是最好的解决方案?
我这样想:在worker线程中创建一个workher线程,在5秒内创建一个timer对象,并在调用Block之前和之后调用gettickcount,然后计算增量。
此外,我将定义一个布尔IsReturned,指示是否已返回块函数。在阻止调用之后将其设置为true。
根据计时器函数中的布尔值,我决定如何进行:
此外,在块函数返回后,我检查增量是否是lett,然后5秒,并将APC OnSucess排队。(问题是退出调用线程是否也会取消计时器?因为基本上在那之后计时器是无用的)
如果我能确定我可以取消计时器函数中的工作线程,我想我甚至不需要gettickcount。
谢谢!
发布于 2009-12-16 05:17:24
我建议为此使用助推::线程库。您可以定期检查阻塞线程是否可连接(即仍然工作),然后在5秒后中断它。然后,您需要编写阻塞函数来处理中断和干净的退出。
#include <boost/thread/thread.hpp>
void Block(void)
{
//Do work and periodically call boost::this_thread::sleep()
try
{
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
catch(boost::thread_interrupted const&)
{
return;
}
}
int main(int argc, char *argv[])
{
boost::thread blockThread(Block); //If Block takes arguments, just add them as arguments to the constructor.
time_t startTime = time(NULL);
while(true)
{
if(blockThread.joinable() && (time(NULL) - startTime) > 5)
{
blockThread.interrupt();
}
//Do whatever you want while waiting for the thread to finish.
}
}编辑:查看线程管理文档以获得更多的中断点和boost线程类的定义。
Edit2:如果您在等待阻塞线程完成时不需要在主线程中执行任何工作,并且在Block()中没有处理中断的方便位置,那么您可以使用这样的方法显式地终止线程:
void Block(void)
{
//Do work
}
int main(args)
{
boost::thread blockThread(Block);
//timed_join() returns false if the thread is still running after the specified time.
if(!blockThread.timed_join(boost::posix_time::milliseconds(5000)))
{ //detach() will kill the thread, any memory initialised in Block() will not be freed, any locals may or may not be freed either.
blockThread.detach();
}
}发布于 2009-12-16 02:47:48
我认为您大概有正确的想法,尽管您可能希望将WM_TIMER消息传递到主线程,而不是潜在的阻塞线程。否则,如果线程在计时器触发之前阻塞,则定时器消息可能会丢失!同样,检查主线程而不是工作线程中的运行时间,因为如果Block()阻塞,它将不会返回,并且在Block()之后对GetTickCount()的调用永远不会发生。
要在线程之间进行通信,最简单的方法可能是使用原子变量。您还可以让工作人员在成功时将一条消息传回主线程,如果主线程在5秒计时器触发时没有看到消息,则应该假定工作线程被阻塞。
一般来说,杀死一个阻塞的线程是危险的。Java文档强烈警告不要这样做,如果有的话,C++的问题就更严重了。想想你自己被警告过了!
发布于 2009-12-16 03:58:32
首先,创建线程是一件昂贵的事情,因此,每次对块的调用都这样做可能不是一个好主意。
第二,解决这个问题的方法有很多,这在很大程度上取决于您的环境。例如,在Windows中,一种可能的方法是有一个带有消息队列的工作线程。然后,定义在工作线程中处理的几条消息。一个可以是WM_CALLBLOCK,另一个可以是WM_AREYOUREADY和WM_YESIAM,当您想要调用Block()时,您可以将该消息发布到工作线程,然后它将调用该函数。有了这条消息,您还可以传递块()所需的任何参数。因为您的函数是阻塞的-如果您然后发布消息WM_AREYOUREADY,您将不会直接得到一个WM_YESIAM回复。这样你就可以建立你的超时值了。
https://stackoverflow.com/questions/1911563
复制相似问题