开发者

Start new thread without blocking/waiting of main operation

Maybe there is a really simple solution for my problem, but I'm really confused with all the boosts around me.

Here's my problem:

I want to start a task (calculation, file system operations, etc.), raised by a callback system which calls the CallbackReceived function and I want to pass this operation to a thread, typically represented by a member function of an object. The thread isn't guaranteed to finish, so it should have something to cancel it after some time.

Something like (don't know if this is 100% correct):

// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
  boost::thread tThread(&MyObject::calculate, *&object); 

  boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::开发者_StackOverflow社区seconds(2));
  tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));

  tThread.join();
}

Basically, a tThread.join()` waits for the return of the thread. While waiting, my main could not receive any callbacks that may come in because it's blocked and sleeps.

So what can one do, to run the thread and not to block the calling initial program while executing the operation?


You can call join just when you need the result of the calculations. Something like "Future" pattern. Anyway, you would have to make your thread variable global to the CallBackRecieved function (You can write some wrapper). Note: you can call join, when thread finished its' work - nothing will be blocked.


What do you want to do with the result of calculate?

Your main thread is blocked in the .join().

If you want to handle other callbacks, you have to return to the normal execution flow, waiting for another call.

Then you have to ask yourself what do you do with the result of calculate when it's finished. Maybe the thread can put the result in a shared resource somewhere and finish gracefully.

You must first sort out all what your code is supposed to do ( processing callbacks, starting threads, what to do with the result ) then you can think of implementing it. There are new constructs in boost and C++11 called promise and future that could suit you but first you have to think about what you want.


Actually you could call the callback while your main thread is sleeping. It would just run on the context (stack) of your thread.

You probably don't want to call join at the point you are at but later or never.

Example (pseudocode):

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;
  }
}

You would define the implementations in cpp and the interface in a h file so no circular dependency would arise, since you are only using Main as a argument in the interface a forward declaration would suffice.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜