在不阻塞/等待主操作的情况下启动新线程

时间:2011-09-13 09:37:08

标签: c++ multithreading boost

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

这是我的问题:

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

类似的东西(不知道这是否100%正确):

// ...
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()`等待线程的返回。在等待的时候,我的主要人员无法接收任何可能进入的回调,因为它被阻止并睡觉。

那么可以做什么,运行线程而不是在执行操作时阻止调用初始程序?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

您想对计算结果做什么?

主线程在.join()中被阻止。

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

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

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

答案 2 :(得分:0)

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

您可能不希望在您所在的位置呼叫联接但稍后或从不。

示例(伪代码):

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作为接口中的参数,前向声明就足够了。

//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 */