views:

81

answers:

3

I am looking for the best way to solve the following (c++) problem. I have a function given by some framework, which returns an object. Sometimes it takes just miliseconds, but on some occasions it takes minutes. So i want to stop the execution if it takes longer than let's say 2 seconds. I was thinking about doing it with boost threads. Important sidenote, if the function returns faster than the 2 seconds the program should not wait. So i was thinking about 2 threads:

1.thread: execute function a       
2.thread: run timer                
if(thread 2 exited bevore thread 1) kill thread 1 
else do nothing

I am struggeling a bit the practical implementation. Especially,

  • how do i return an object from a child boost thread to the main thread?
  • how do i kill a thread in boost?
  • is my idea even a good one, is there a better way to solve the problem in c++ (with or without boost)?
A: 

I have done something similar by the past and that works (even though not ideal). To get the return value just "share" a variable (that could be just a pointer (initially nil) to the returned value, or a full object with a state etc ...) and make your thread read/udate it. Don't forget to mutex it needed. That should be quite straight forward.

mb14
A: 

Expanding what James has said above, "kill a thread" is such a harsh term! :) But interruption is not so easy either, typically with boost threads, there needs to be an interruption point, where the running thread can be interrupted. There is a set of these interruptible functions (unfortunately they are boost specific), such as wait/sleep etc. One option you have is in the first thread, liberally scatter interruption_points(). Such that when you call interrupt() once thread 2 dies, at the next interruption_point() thread 1 will throw an exception.

Threads are in the same process space, thus you can have shared state between multiple threads as long as there is synchronized access to that shared state.

EDIT: just noticed that the OP has already looked into this... will leave the answer up anyway I guess...

Nim
the problem with this, is as already described in an obove comment that, i can't place interruption points, my thread function looks only like this: threadfunc(){ myobject = someframework.callfucntion() }
inf.ig.sh
In that case, I think you are stuck, I can think of only one other way around this - fork() and run the first thread as a separate process, and then kill that? The shared state will get messy though, I guess you could get around that with shared memory?
Nim
+1  A: 

As for waiting, just use thread::timed_join() inside your main thread, this will return false, if the thread didn't complete within the given time.

Killing the thread is not feasible if your third-party library is not aware of boost:threads. Also, you almost certainly don't want to 'kill' the thread without giving the function the possibility to clean up.

I'd suggest that you wait for, say, 2 seconds and then continue with some kind of error message, letting the framework function finish its work and just ignoring the result if it came too late.

As for returning a value, I'd suggest something like

struct myfunction {
   MyObj returnValue;
   void operator() () { 
     // ... 
     returnValue = theComputedReturnValue;
   }
};

// ...
myfunction f;
boost::thread t = boost::thread(boost::ref(f));
t.join(); // or t.timed_join()...
use(f.returnValue); 
// ...
MartinStettner
Thanks looks like it works. There is just one type in the post it should be operator()() in line 3.
inf.ig.sh
Thanks, I fixed it ...
MartinStettner