How to stop a function from running from outside in c++ - c++

I want to run a function and tell if the function didn't finish after n milliseconds, stop that function and start another one. something like this code:
void run()
{
//do something that doesn't have while(1)
}
void main()
{
run();
if(runFunctionDidntFinishInSeconds(10)
{
endPrintFunction();
backupPlan();
}
return 0;
}
I searched out and found boost::timed_join function. here's my code:
void run()
{
int a;
for (int i = 0; i < 2000; i++)
cout << i << endl;
}
int main()
{
boost::thread t = new boost::thread(&run);
if (t.timed_join(boost::posix_time::microseconds(10000))){
cout << "done" << endl;
}
else{
cout << endl << "not done" << endl;
}
system("pause");
return 0;
}
but it doesn't stop thread 't' from running. I went to terminate the thread, but it's not a good option.
I want the 'a' function to finish the exact time I'm telling it to.
The system gets input every 16ms and I want to do a processing on it and say if the processing took more than about 13ms leave it and go do a backup plan. and I want it to be abstracted from the ones who write the processing method. So putting a while loop on the top of it brings me delay.
What should i do?
The least I think I need is to be abled to reset the processing thread to do what it had needed to do again!

I think your are looking for something like std::future.
http://en.cppreference.com/w/cpp/thread/future/wait_for
You can start the function in another thread and wait until the function returns or has a timeout.
For your example:
std::future< void > future = std::async( std::launch::async, print );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferred\n";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeout\n";
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!\n";
}
However this doesn't cause the detached thread to end. For this it is necessary to include a flag on startup, so the detached thread can cleanup and exit savely on its own.
void run(const std::atomic_bool& cancelled)
{
int a;
for (int i = 0; i < 2000; i++)
{
cout << i << endl;
if (cancelled)
return;
}
}
std::atomic_bool cancellation_token = false;
std::future< void > future = std::async( std::launch::async,
run,
std::ref(cancellation_token) );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferred\n";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeout\n";
cancellation_token = true;
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!\n";
}

I want it to be abstracted from the ones who write the processing method.
Standard C++ does not have a way to forcibly interrupt the control flow of a function from outside of that function's call graph (a function it calls can throw, but someone can't throw for them).
OS-specific thread systems have ways to terminate a thread. However, this leaves the program potentially in an undefined state, as the destructors for any stack variables have not been called. And since you didn't know where it was in that processing when you killed it, you can't effectively clean up after it. Even a C program cannot guarantee that an arbitrary function can be terminated; it would have to be one which did not dynamically allocate memory or other resources that have to be cleaned up.
You can compensate for this by coding your function very carefully. But that requires that the person who wrote that function to code it very carefully. And thus, there isn't an abstraction, since the person writing the function has to know what the rules are and is required to follow them.
So the only solution that works requires cooperation. The function must either be written in such a way that it can safely be stopped via those OS-dependent features, or it must be written to periodically check some value and stop itself.

Here are two and 3/4 approaches.
The first requires that the code you want to halt cooperates. It either polls some variable while it runs, or it calls a function periodically that could throw an exception to halt execution. boost interruptable threads follow the second model.
The second requires you to launch a new process, marshall your data over to the function, and use IPC to get the information back. If the function doesn't return in time, you kill the child process.
The third "half" involves rewriting the code in a different language, or using C++ as a scripting language. You run the code in an interpreter that does the first or second solution for you.
Now, a practical alternative (a 1/4 solution) is to make sure the function is purely functional, run it in a separate thread with a semi-reliable abort message (like the first one), and discard its return value if it takes too long. This doesn't do what you want, but is far easier.

There's a way with atomics used as semaphores but this will emit full blown memory barriers and thus decrease the performance because of the load every iteration :
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
std::atomic<bool> printFinished { false };
std::atomic<bool> shouldPrintRun { true };
void print()
{
while (shouldPrintRun.load() /* && your normal stop condition*/)
{
//work..
}
printFinished.store(true);
}
int main()
{
std::thread t(print);
std::this_thread::sleep_for(std::chrono::seconds(10));
if (!printFinished.load())
{
shouldPrintRun.store(false);
t.join();
std::cout << "help!";
}
return 0;
}
If you don't want your function that's ran on another thread to check back if it needs to stop then terminating that thread is the only option.

A possible solution is that you have to make that the lengthy function into small & short incremental function which will continue the task still every time it is call from the last time it left of. The code below which can be run in a thread will do similar job of a time slicer and can be terminated at will.
void Process()
{
bool flag = true;
while (running)
{
std::chrono::high_resolution_clock::time_point time1 = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds span(16);
while ( (std::chrono::high_resolution_clock::now() - time1 ) < span)
{
flag ? incremental_function1() : incremental_function2();
if (!running) return;
}
flag = (!flag);
}
}

Related

How can I kill a function after a timeout in Qt?

I have a function, let's call it foo().
void foo()
{
int count = 0;
while(1)
{
count ++;
if(count>= 30000)
{
count = 0;
}
}
}
foo() will run indefinitely, but let's say I want to fun my function foo() after 1 minute.
How can I do that using Qt?
I have already seen some people talking about one shot Qtime, but all the examples I have seen are about running my function after the timeout, but never killing it.
You shouldn't kill threads but instead give them a condition to check if they should continue or quit. One way could use an atomic<bool> so that you can set it from another thread. You could also limit the time by measuring how long time the function has executed.
Example:
#include <atomic>
#include <chrono>
void foo(std::atomic<bool>& run) {
auto end_at = std::chrono::steady_clock::now() + std::chrono::minutes(1);
while(run == true && std::chrono::steady_clock::now() < end_at) {
count++;
}
}
Setting run to false from another thread would signal foo() to quit and if it runs for longer than a minute it'll also quit.

Which types of memory_order should be used for non-blocking behaviour with an atomic_flag?

I'd like, instead of having my threads wait, doing nothing, for other threads to finish using data, to do something else in the meantime (like checking for input, or re-rendering the previous frame in the queue, and then returning to check to see if the other thread is done with its task).
I think this code that I've written does that, and it "seems" to work in the tests I've performed, but I don't really understand how std::memory_order_acquire and std::memory_order_clear work exactly, so I'd like some expert advice on if I'm using those correctly to achieve the behaviour I want.
Also, I've never seen multithreading done this way before, which makes me a bit worried. Are there good reasons not to have a thread do other tasks instead of waiting?
/*test program
intended to test if atomic flags can be used to perform other tasks while shared
data is in use, instead of blocking
each thread enters the flag protected part of the loop 20 times before quitting
if the flag indicates that the if block is already in use, the thread is intended to
execute the code in the else block (only up to 5 times to avoid cluttering the output)
debug note: this doesn't work with std::cout because all the threads are using it at once
and it's not thread safe so it all gets garbled. at least it didn't crash
real world usage
one thread renders and draws to the screen, while the other checks for input and
provides frameData for the renderer to use. neither thread should ever block*/
#include <fstream>
#include <atomic>
#include <thread>
#include <string>
struct ThreadData {
int numTimesToWriteToDebugIfBlockFile;
int numTimesToWriteToDebugElseBlockFile;
};
class SharedData {
public:
SharedData() {
threadData = new ThreadData[10];
for (int a = 0; a < 10; ++a) {
threadData[a] = { 20, 5 };
}
flag.clear();
}
~SharedData() {
delete[] threadData;
}
void runThread(int threadID) {
while (this->threadData[threadID].numTimesToWriteToDebugIfBlockFile > 0) {
if (this->flag.test_and_set(std::memory_order_acquire)) {
std::string fileName = "debugIfBlockOutputThread#";
fileName += std::to_string(threadID);
fileName += ".txt";
std::ofstream writeFile(fileName.c_str(), std::ios::app);
writeFile << threadID << ", running, output #" << this->threadData[threadID].numTimesToWriteToDebugIfBlockFile << std::endl;
writeFile.close();
writeFile.clear();
this->threadData[threadID].numTimesToWriteToDebugIfBlockFile -= 1;
this->flag.clear(std::memory_order_release);
}
else {
if (this->threadData[threadID].numTimesToWriteToDebugElseBlockFile > 0) {
std::string fileName = "debugElseBlockOutputThread#";
fileName += std::to_string(threadID);
fileName += ".txt";
std::ofstream writeFile(fileName.c_str(), std::ios::app);
writeFile << threadID << ", standing by, output #" << this->threadData[threadID].numTimesToWriteToDebugElseBlockFile << std::endl;
writeFile.close();
writeFile.clear();
this->threadData[threadID].numTimesToWriteToDebugElseBlockFile -= 1;
}
}
}
}
private:
ThreadData* threadData;
std::atomic_flag flag;
};
void runThread(int threadID, SharedData* sharedData) {
sharedData->runThread(threadID);
}
int main() {
SharedData sharedData;
std::thread thread[10];
for (int a = 0; a < 10; ++a) {
thread[a] = std::thread(runThread, a, &sharedData);
}
thread[0].join();
thread[1].join();
thread[2].join();
thread[3].join();
thread[4].join();
thread[5].join();
thread[6].join();
thread[7].join();
thread[8].join();
thread[9].join();
return 0;
}```
The memory ordering you're using here is correct.
The acquire memory order when you test and set your flag (to take your hand-written lock) has the effect, informally speaking, of preventing any memory accesses of the following code from becoming visible before the flag is tested. That's what you want, because you want to ensure that those accesses are effectively not done if the flag was already set. Likewise, the release order on the clear at the end prevents any of the preceding accesses from becoming visible after the clear, which is also what you need so that they only happen while the lock is held.
However, it's probably simpler to just use a std::mutex. If you don't want to wait to take the lock, but instead do something else if you can't, that's what try_lock is for.
class SharedData {
// ...
private:
std::mutex my_lock;
}
// ...
if (my_lock.try_lock()) {
// lock was taken, proceed with critical section
my_lock.unlock();
} else {
// lock not taken, do non-critical work
}
This may have a bit more overhead, but avoids the need to think about atomicity and memory ordering. It also gives you the option to easily do a blocking wait if that later becomes useful. If you've designed your program around an atomic_flag and later find a situation where you must wait to take the lock, you may find yourself stuck with either spinning while continually retrying the lock (which is wasteful of CPU cycles), or something like std::this_thread::yield(), which may wait for longer than necessary after the lock is available.
It's true this pattern is somewhat unusual. If there is always non-critical work to be done that doesn't need the lock, commonly you'd design your program to have a separate thread that just does the non-critical work continuously, and then the "critical" thread can just block as it waits for the lock.

Start multiple threads and wait only for one to finish to obtain results

Assuming I have the function double someRandomFunction(int n) that takes an integer and returns double but it's random in the sense that it tries random stuff to come up with the solution so even though you run the function with the same arguments, sometimes it can take 10 seconds to finish and other 40 seconds to finish.
The double someRandomFunction(int n) functions itself is a wrapper to a black box function. So the someRandomFunction takes a while to complete but I don't have control in the main loop of the black box, hence I can't really check for a flag variable within the thread as the heavy computation happens in a black box function.
I would like to start 10 threads calling that function and I am interested in the result of the first thread which finishes first. I don't care which one it's I only need 1 result from these threads.
I found the following code:
std::vector<boost::future<double>> futures;
for (...) {
auto fut = boost::async([i]() { return someRandomFunction(2) });
futures.push_back(std::move(fut));
}
for (...) {
auto res = boost::wait_for_any(futures.begin(), futures.end());
std::this_thread::yield();
std::cout << res->get() << std::endl;
}
Which is the closest to what I am looking for, but still I can't see how I can make my program to terminate the other threads as far as one thread returns a solution.
I would like to wait for one to finish and then carry on with the result of that one thread to continue my program execution (i.e., I don't want to terminate my program after I obtain that single result, but I would like to use it for the remaining program execution.).
Again, I want to start up 10 threads calling the someRandomFunction and then wait for one thread to finish first, get the result of that thread and stop all the other threads even though they didn't finish their work.
If the data structure supplied to the black-box has some obvious start and end values, one way to make it finish early could be to change the end value while it's computing. It could of course cause all sorts of trouble if you've misunderstood how the black-box must work with the data, but if you are reasonably sure, it can work.
main spawns 100 outer threads that each spawn one inner thread that calls the blackbox. The inner thread receives the blackbox result and notifies all waiting threads that it's done. The outer thread waits for any inner thread to get done and then modifies the data for its own blackbox to trick it to finish.
No polling (except for the spurious wakeup loops) and no detached threads.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <chrono>
// a work package for one black-box
struct data_for_back_box {
int start_here;
int end_here;
};
double blackbox(data_for_back_box* data) {
// time consuming work here:
for(auto v=data->start_here; v<data->end_here; ++v) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
// just a debug
if(data->end_here==0) std::cout << "I was tricked into exiting early\n";
return data->end_here;
}
// synchronizing stuff and result
std::condition_variable cv;
std::mutex mtx;
bool done=false;
double result;
// a wrapper around the real blackbox
void inner(data_for_back_box* data) {
double r = blackbox(data);
if(done) return; // someone has already finished, skip this result
// notify everyone that we're done
std::unique_lock<std::mutex> lock(mtx);
result = r;
done=true;
cv.notify_all();
}
// context setup and wait for any inner wrapper
// to signal "done"
void outer(int n) {
data_for_back_box data{0, 100+n*n};
std::thread work(inner, &data);
{
std::unique_lock<std::mutex> lock(mtx);
while( !done ) cv.wait(lock);
}
// corrupt data for blackbox:
data.end_here = 0;
// wait for this threads blackbox to finish
work.join();
}
int main() {
std::vector<std::thread> ths;
// spawn 100 worker threads
for(int i=0; i<100; ++i) {
ths.emplace_back(outer, i);
}
double saved_result;
{
std::unique_lock<std::mutex> lock(mtx);
while( !done ) cv.wait(lock);
saved_result = result;
} // release lock
// join all threads
std::cout << "got result, joining:\n";
for(auto& th : ths) {
th.join();
}
std::cout << "result: " << saved_result << "\n";
}

Wait until any task completed

I am trying to write a simple task class. It is a wrapper around std::future, it holds its state (not_started, running, completed), can start processing of given job on demand and it can repeatedly return result of its processing.
I can also offer some global functions for work with these tasks. But I am a little bit stuck in writing size_t wait_any(std::vector<task<T>>& tasks) function. This function is given a vector of tasks and should return index of the first completed task. If there are more tasks completed at the beginning, one of them must be returned (but this is not the problem).
A simple implementation using active waiting is following:
template <typename T>
size_t wait_any(std::vector<task<T>>& tasks) {
if (tasks.size() == 0) throw std::exception("Waiting for empty vector of tasks!");
for (auto i = tasks.begin(); i != tasks.end(); ++i) {
(*i).try_start();
}
while (true) {
for (size_t i = 0; i != tasks.size(); ++i) {
if (tasks[i].is_completed()) return i;
}
}
}
I would appreciate passive waiting for any completition. A std::this_thread::yield function is available, but I would rather not use it. As mentioned in documentation:
The exact behavior of this function depends on the implementation, in particular on the mechanics of the OS scheduler in use and the state of the system.
It seems that I should use std::condition_variable and std::mutex to get the whole thing working. There are a lot of examples showing use of these things, but I do not understand it at all and I have not found solution for this particular problem.
I would guess that I should create a std::condition_variable (just cv further) in the wait_any function. Then this cv (pointer) should be registered to all tasks from given vector. Once any of the tasks is completed (I can handle the moment when a task is done) it should call std::condition_variable::notify_one for all cv's registered in this task. These notified cv's should be also removed from all tasks which are holding them.
Now, I do not know how to use mutexes. I probably need to prevent multiple calls of notification and many other problems.
Any help appreciated!
I was thinking that since you only need one notification, you can use std::call_once to set the task_id which you require.
A naive way to go about it would be:
#include <iostream>
#include <vector>
#include <thread>
std::once_flag lala;
std::atomic_int winner( -1 );
void silly_task( int task_id )
{
//do nothing
std::call_once ( lala, [&]()
{
std::cout << "thread " << task_id << " wins" << std::endl;
winner = task_id;
} );
}
int main(){
std::vector<std::thread> vt;
for ( int i=0; i < 10 ; i ++ )
{
vt.push_back( std::thread( &silly_task, i) );
}
while ( winner == -1 )
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
for ( int i=0; i < 10 ; i ++ )
{
vt[i].join();
}
return 0;
} // end main

Timer takes longer to reach 10.f seconds if std::cout is commented

I have a weird problem with the value returned by my class called Timer (that uses std::chrono).
If I keep the std::cout commented, I have the feeling that delta returned by timer.restart() gets a very low value (it takes 3 or 4 times longer to reach 10.f). I tried to display it, but as I said above, uncommenting the std::cout solves the problem.
My timer does its job well in others parts of the application, so I don't think the problem is in there.
void Party::gameOver(float delta)
{
_delta += delta;
// std::cout << _delta << std::endl; // if I uncomment this the problem is solved
if (_delta > 10.0000f) {
// ...
_state = GameStatusType::Waiting;
_delta = 0;
}
}
This method is called here:
void Party::loop(void)
{
Timer timer;
while (!isFinished())
{
float delta = timer.restart(); // return in second
switch (_state)
{
// ...
case GameStatusType::GameOver:
gameOver(delta);
break;
}
}
}
The method "loop" is called in a thread like below:
void Party::run(void)
{
_party = std::thread(&Party::loop, shared_from_this());
}
I don't know if this can help, but I execute this code on Visual Studio 2015 on Windows 10. If you need further information, just ask.
One possibility is the windows console is really slow, there was many topic about this. You may try use overlapped io to write to console to see if it's improved.
The problem was just the loop was going too fast. Just added a Sleep.