首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程同步

线程同步
EN

Stack Overflow用户
提问于 2009-12-16 00:47:53
回答 3查看 723关注 0票数 0

假设我有一个阻塞方法,让我们在Block()中调用。

由于我不希望我的主线程阻塞,我可能会创建一个工作线程,相反,它将调用Block。

不过,我还有另外一个条件。

我希望调用阻止在5秒内返回顶部,否则,我想让主线程知道对块的调用失败,并退出工作线程。

对于这种情况,什么才是最好的解决方案?

我这样想:在worker线程中创建一个workher线程,在5秒内创建一个timer对象,并在调用Block之前和之后调用gettickcount,然后计算增量。

此外,我将定义一个布尔IsReturned,指示是否已返回块函数。在阻止调用之后将其设置为true。

根据计时器函数中的布尔值,我决定如何进行:

  1. 如果布尔值为真,我什么也不做。
  2. 如果布尔值为false,我可以在主线程上排队OnFailure或发送Sucess事件信号,然后强制退出工作线程(问题是我不确定是否能做到这一点)

此外,在块函数返回后,我检查增量是否是lett,然后5秒,并将APC OnSucess排队。(问题是退出调用线程是否也会取消计时器?因为基本上在那之后计时器是无用的)

如果我能确定我可以取消计时器函数中的工作线程,我想我甚至不需要gettickcount。

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-16 05:17:24

我建议为此使用助推::线程库。您可以定期检查阻塞线程是否可连接(即仍然工作),然后在5秒后中断它。然后,您需要编写阻塞函数来处理中断和干净的退出。

代码语言:javascript
复制
#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()中没有处理中断的方便位置,那么您可以使用这样的方法显式地终止线程:

代码语言:javascript
复制
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();
    }
}
票数 2
EN

Stack Overflow用户

发布于 2009-12-16 02:47:48

我认为您大概有正确的想法,尽管您可能希望将WM_TIMER消息传递到主线程,而不是潜在的阻塞线程。否则,如果线程在计时器触发之前阻塞,则定时器消息可能会丢失!同样,检查主线程而不是工作线程中的运行时间,因为如果Block()阻塞,它将不会返回,并且在Block()之后对GetTickCount()的调用永远不会发生。

要在线程之间进行通信,最简单的方法可能是使用原子变量。您还可以让工作人员在成功时将一条消息传回主线程,如果主线程在5秒计时器触发时没有看到消息,则应该假定工作线程被阻塞。

一般来说,杀死一个阻塞的线程是危险的。Java文档强烈警告不要这样做,如果有的话,C++的问题就更严重了。想想你自己被警告过了!

票数 2
EN

Stack Overflow用户

发布于 2009-12-16 03:58:32

首先,创建线程是一件昂贵的事情,因此,每次对块的调用都这样做可能不是一个好主意。

第二,解决这个问题的方法有很多,这在很大程度上取决于您的环境。例如,在Windows中,一种可能的方法是有一个带有消息队列的工作线程。然后,定义在工作线程中处理的几条消息。一个可以是WM_CALLBLOCK,另一个可以是WM_AREYOUREADY和WM_YESIAM,当您想要调用Block()时,您可以将该消息发布到工作线程,然后它将调用该函数。有了这条消息,您还可以传递块()所需的任何参数。因为您的函数是阻塞的-如果您然后发布消息WM_AREYOUREADY,您将不会直接得到一个WM_YESIAM回复。这样你就可以建立你的超时值了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1911563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档