首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >启动新线程,不阻塞/等待主操作

启动新线程,不阻塞/等待主操作
EN

Stack Overflow用户
提问于 2011-09-13 17:37:08
回答 3查看 4.8K关注 0票数 3

也许我的问题有一个非常简单的解决方案,但我真的对周围所有的提升感到困惑。

这就是我的问题:

我希望启动一个任务(计算、文件系统操作等),该任务由调用CallbackReceived函数的回调系统引发,并且我希望将此操作传递给一个线程,该线程通常由对象的成员函数表示。线程不能保证完成,所以在一段时间后它应该有一些东西来取消它。

类似于(不知道这是不是100%正确):

代码语言:javascript
复制
// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
  boost::thread tThread(&MyObject::calculate, *&object); 

  boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2));
  tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));

  tThread.join();
}

基本上,tThread.join()`等待线程的返回。在等待期间,我的main无法接收任何可能传入的回调,因为它被阻塞并处于休眠状态。

那么,如何才能运行线程,并且在执行操作时不阻塞调用的初始程序呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-13 17:54:29

如何处理calculate的结果?

您的主线程在.join()中被阻塞。

如果您想要处理其他回调,则必须返回到正常的执行流程,等待另一个调用。

然后你必须问自己,当计算完成时,你会怎么处理它的结果。也许线程可以将结果放在某个共享资源中,然后优雅地结束。

你必须首先整理出你的代码应该做的所有事情(处理回调、启动线程、如何处理结果),然后才能考虑实现它。boost和C++11中有称为promise和future的新结构,它们可能适合您,但首先您必须考虑您想要什么。

票数 2
EN

Stack Overflow用户

发布于 2011-09-13 17:47:32

您可以在需要计算结果时调用join。类似于“未来”模式。无论如何,您必须使线程变量成为CallBackRecieved函数的全局变量(您可以编写一些包装器)。注意:当线程完成它的工作时,你可以调用join --没有什么会被阻塞。

票数 4
EN

Stack Overflow用户

发布于 2011-09-13 18:02:44

实际上,您可以在主线程处于休眠状态时调用回调。它只会在你的线程的上下文(栈)上运行。

您可能不想在此时调用join,但请稍后调用,否则永远不会调用。

示例(伪代码):

代码语言:javascript
复制
class Worker {

  void doWork(void * mainthread){

    Main* main = static_cast<Main*>(mainthread);

    while(hasWorkTodo){
      //work

      //inform main
      main->callbackwithinformation(information);

  }


}


class Main{

  atomi_int filesfound;

  void main_part(){
    //start worker
    boost::thread thread(&Worker::doWork, &object, this);

    while(hasworktodo){
      //do work

      //use filesfound here
    }   
    //About to finish make sure we join our thread
    thread.join();

  }

  void callbackwithinformation(int updatedcount){
    //here we set a flag or pass some object
    //probably will need an atomic operation
    filesfound = updatedcount;
  }
}

您可以在cpp中定义实现,并在h文件中定义接口,这样就不会出现循环依赖,因为您只在接口中使用Main作为参数,向前声明就足够了。

代码语言:javascript
复制
//worker.h
class mainthread;

class Worker {    
  void doWork(void * mainthread);
}

//worker.cpp
#include "main.h"
void Worker::doWork(/* and so on*/}


//main.h
class Main{

  atomi_int filesfound;

  void main_part();

  void callbackwithinformation(int updatedcount);
}

//main.cpp
//no need for worker.h here
void Main::main_part() /* implementation and so on */
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7399711

复制
相关文章

相似问题

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