I am running an asynchronous task and want to cancel it when a certain condition (bool) is met.
void MyClass::createTask()
{
this->future = std::async(std::launch::async, [this](){
while(this->CONDITION == false)
{
// do work
}
});
}
void MyClass::cancelTask()
{
this->CONDITION = true;
this->future.get();
}
Obviously, calling MyClass::cancelTask() would cause a data-race, because this->CONDITION is being written to and read from at the same time. So the first thing that came to my mind is to use a std::mutex. However that would mean that the task has to lock and unlock the mutex on every new iteration of the while-loop. Since the async task is performance critical, this seems like a bad choice.
Is there a cleaner, and especially a more perfomant way to achieve what I am trying to do? Switching from std::async to std::thread would be ok if it enabled an efficient solution.
As far as I know there is no elegant way to close a thread/async task in C++.
A simple way is to use std::atomic<bool> or std::atomic_flag instead of a mutex.
If you are familiar with boost library, than you could use boost::thread with interruption_points.
I have a solution for this kind of requeirements. I use std::mutex, std::condition_variable and std::unique_lock<std::mutex> to create tow methods: pauseThread and resumeThread.
The idea is use the condition_variable and unique_lock to make the thread wait for a time, for example 5 seconds, and after the time os over the thread continue its execution. But, if you want to interrupt the condition_variable you could use its method notify_one().
Using your code, and continue with your idea, i made some changes to your class:
MODIFICATION: I modify the flag bKeepRunning.
MyClass.h
#include <mutex>
#include <chrono>
#include <future>
#include <atomic>
class MyClass
{
std::atomic<bool> bKeepRunning;
std::mutex mtx_t;
std::condition_variable cv_t;
std::future<void> _future;
public:
MyClass();
~MyClass();
void createTask();
void stopTask();
void pauseThread(int time);
void resumeThread();
}
MyClass.cpp
#include "MyClass.h"
#include <iostream>
using namespace std;
MyClass::MyClass()
{
bKeepRunning = false;
}
MyClass::~MyClass()
{
}
void MyClass::createTask()
{
bKeepRunning = true;
_future = std::async(std::launch::async, [this]() {
int counter = 0;
cout << "Thread running" << endl;
while (bKeepRunning)
{
counter++;
cout << "Asynchronous thread counter = [" << counter << "]" << endl;
this->pauseThread(5);//Wait for 5 seconds
}
cout << "Thread finished." << endl;
});
}
void MyClass::stopTask()
{
cout << "Stoping Thread." << endl;
bKeepRunning = false;
resumeThread();
}
void MyClass::pauseThread(int time)
{
std::unique_lock<std::mutex> lck_t(mtx_t);
cv_t.wait_for(lck_t, chrono::seconds(time));
}
void MyClass::resumeThread()
{
cout << "Resumming thread" << endl;
cv_t.notify_one();
}
I made a console sample to show how it works:
Main.cpp
#include <iostream>
#include <sstream>
#include <string>
#include "MyClass.h"
using namespace std;
int main(int argc, char* argv[])
{
MyClass app;
char line[80];
cout << "Press Enter to stop thread." << endl;
app.createTask();
cin.getline(line,80);
app.stopTask();
}
If you need some other period of time to pause your thread, you can try to change the interval and time of chrono::seconds(time) to, for example, chrono::milliseconds(time) that is using milliseconds.+
At the end, if you execute this sample, you could get an output like:
Related
I'm trying to capture thread_pool object in a lambda function. This lambda function is called inside a thread. Upon this call, it creates(obtains) a new thread with asio::post. However, it throws segmentation fault. I tried create weak ptr with shared_ptr<thread_pool> but it didn't work as well. Simple example written below,
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
void thread1(std::function<void()> createThread) {
createThread();
}
void thread2() {
cout << "You made it" << std::endl;
}
int main(int argc, char **argv) {
boost::asio::thread_pool pool(std::thread::hardware_concurrency());
std::function<void()> createThread;
createThread = [&pool] () {
boost::asio::post(pool, boost::bind(thread2));
return true;
};
boost::asio::post(pool, boost::bind(thread1, createThread));
pool.join();
}
It works if I create another thread_pool object inside the lambda function. However, this is not the right way to do this. Therefore, I am open for your suggestions.
Edit: Added libraries to code snippet and removed while loop.
I'd simplify:
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
void thread1(std::function<void()> createThread) {
createThread();
while (true) {
std::cout << "Sleeping" << std::endl;
sleep(1);
}
}
void thread2() { std::cout << "You made it" << std::endl; }
int main() {
boost::asio::thread_pool pool;
post(pool,
boost::bind(thread1, [&pool]() { post(pool, boost::bind(thread2)); }));
pool.join();
}
Note the endl that forces stdout to flush, which helps getting results you can expect.
HOWEVER
There's a code smell with:
using explicit "threads" when using a thread-pool
nullary bind expressions
createThread doesn't (create a thread)
passing references to execution contexts. Instead, pass executors
Applying these:
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
using Executor = boost::asio::thread_pool::executor_type;
void task_loop(Executor ex, std::function<void()> task) {
while (true) {
post(ex, task);
sleep(1);
}
}
void task_function() { std::cout << "Task executes" << std::endl; }
int main() {
boost::asio::thread_pool pool;
post(pool, boost::bind(task_loop, pool.get_executor(), task_function));
pool.join();
}
Prints each second:
Task executes
Task executes
...
Is this one what you look for? :
typedef std::unique_ptr<boost::asio::io_service::work> work_ptr;
std::atomic<bool> closeFlag(false);
int main(int argc, char** argv) {
boost::asio::io_service service;
// keep the workers occupied
work_ptr work(new boost::asio::io_service::work(service));
boost::thread_group workers;
for(size_t i = 0; i < std::thread::hardware_concurrency(); ++i) {
workers.create_thread([&service]() {
service.run();
});
}
service.post([] { std::cout << "You made first job"; });
service.post([] { std::cout << "You made second job"; });
while(!closeFlag) {
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
service.stop();
work.reset(); // destroy work object: signals end of work
workers.join_all(); // wait for all worker threads to finish
return 0;
}
I'm working on simple cancellation mechanism. But I have found problem with waiting for timeout on condition variable.
Lets consider the sample program from:
https://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/
It looks like this sample is broken. If someone would provide the data very fast then the program would go into infinite loop. To visualize it I did little modification to the sample program:
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
using namespace std::chrono_literals;
std::condition_variable cv;
int value = -1;
void compute() {
value = 0;;
cv.notify_one();
}
int main()
{
std::thread th(compute);
std::this_thread::sleep_for(1s);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (cv.wait_for(lck, std::chrono::seconds(1)) == std::cv_status::timeout) {
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
As I can't type as fast I just set the value to 0 and execute notify_one.
On the main thread I simulate simple delay. sleep_for(1s).
Finally the program does not see the notify_one and loops infinitely.
The output is: .....
My question is how to implement it correctly ?
I would like to know also if the waiting was stopped by timeout.
If the notify happens before the wait then it indeed gets "lost".
Most usage of CVs also require a flag of some sort which should be checked in the predicate. You already have this flag - value. Just use this as a predicate:
EDIT: Removed wrong code.
Note that as a separate matter you should protect the writing to value with your mutex or you're likely to hit UB. Which means you need to make your mutex global along with the CV/Flag.
Better way:
auto endTime = std::chrono::now() + std::chrono::seconds(1);
while(flag != 0)
{
auto res = cv.wait_until(lck, endTime);
if (res == std::cv_status::timeout)
{
// Add Timeout logic here
break;
}
}
I'm trying to write a program with c++11 in which multiple threads are run, and, during each cycle the main thread will wait for each thread to be finished. The program below is a testing program for this concept.
Apparently I'm missing something trivial in my implementation as it looks like I'm experiencing a deadlock (Not always, just during some random runs).
#include <iostream>
#include <stdio.h>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <mutex>
using namespace std;
class Producer
{
public:
Producer(int a_id):
m_id(a_id),
m_ready(false),
m_terminate(false)
{
m_id = a_id;
m_thread = thread(&Producer::run, this);
// ensure thread is available before it is started
this_thread::sleep_for(std::chrono::milliseconds(100));
}
~Producer() {
terminate();
m_thread.join();
}
void start() {
//cout << "start " << m_id << endl;
unique_lock<mutex> runLock(m_muRun);
m_ready = true;
runLock.unlock();
m_cond.notify_all();
}
void wait() {
cout << "wait " << m_id << endl;
unique_lock<decltype(m_muRun)> runLock(m_muRun);
m_cond.wait(runLock, [this]{return !m_ready;});
}
void terminate() {
m_terminate = true;
start();
}
void run() {
do {
unique_lock<decltype(m_muRun)> runLock(m_muRun);
m_cond.wait(runLock, [this]{return m_ready;});
if (!m_terminate) {
cout << "running thread: " << m_id << endl;
} else {
cout << "exit thread: " << m_id << endl;
}
runLock.unlock();
m_ready = false;
m_cond.notify_all();
} while (!m_terminate);
}
private:
int m_id;
bool m_ready;
bool m_terminate;
thread m_thread;
mutex m_muRun;
condition_variable m_cond;
};
int main()
{
Producer producer1(1);
Producer producer2(2);
Producer producer3(3);
for (int i=0; i<10000; ++i) {
cout << i << endl;
producer1.start();
producer2.start();
producer3.start();
producer1.wait();
producer2.wait();
producer3.wait();
}
cout << "exit" << endl;
return 0;
}
The program's output when the deadlock is occurring:
....
.......
running thread: 2
running thread: 1
wait 1
wait 2
wait 3
running thread: 3
Looking at the program's output when the deadlock occurs, I suspect the bottleneck of the program is that sometimes the Producer::wait function is called, before the corresponding thread is actually started, i.e. the command Producer::start should have triggered the start, a.k. unlocking of the mutex, however it is not yet picked up by the thread's run method (Producer::run), (NB: I'm not 100% sure of this!). I'm a bit lost here, hopefully somebody can provide some help.
You have race condition in this code:
runLock.unlock();
m_ready = false;
m_ready variable must be always protected by mutex for proper synchronization. And it is completely unnecessary to wait for thread to start this_thread::sleep_for() - proper synchronization would take care of that as well so you can simply remove that line. Note this is pretty inefficient way of doing proper multithreading - there should be thread pool instead of individual object with separate mutex and condition variable each.
I have a c++ class that allocates a lot of memory. It does this by calling a third-party library that is designed to crash if it cannot allocate the memory, and sometimes my application creates several instances of my class in parallel threads. With too many threads I have a crash.
My best idea for a solution is to make sure that there are never, say, more than three instances running at the same time. (Is this a good idea?)
And my current best idea for implementing that is to use a boost mutex. Something along the lines of the following pseudo-code,
MyClass::MyClass(){
my_thread_number = -1; //this is a class variable
while (my_thread_number == -1)
for (int i=0; i < MAX_PROCESSES; i++)
if(try_lock a mutex named i){
my_thread_number = i;
break;
}
//Now I know that my thread has mutex number i and it is allowed to run
}
MyClass::~MyClass(){
release mutex named my_thread_number
}
As you see, I am not quite sure of the exact syntax for mutexes here.. So summing up, my questions are
Am I on the right track when I want to solve my memory error by limiting the number of threads?
If yes, Should I do it with mutexes or by other means?
If yes, Is my algorithm sound?
Is there a nice example somewhere of how to use try_lock with boost mutexes?
Edit: I realized I am talking about threads, not processes.
Edit: I am involved in building an application that can run on both linux and Windows...
UPDATE My other answer addresses scheduling resources among threads (after the question was clarified).
It shows both a semaphore approach to coordinate work among (many) workers, and a thread_pool to limit workers in the first place and queue the work.
On linux (and perhaps other OSes?) you can use a lock file idiom (but it's not supported with some file-systems and old kernels).
I would suggest to use Interprocess synchronisation objects.
E.g., using a Boost Interprocess named semaphore:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread.hpp>
#include <cassert>
int main()
{
using namespace boost::interprocess;
named_semaphore sem(open_or_create, "ffed38bd-f0fc-4f79-8838-5301c328268c", 0ul);
if (sem.try_wait())
{
std::cout << "Oops, second instance\n";
}
else
{
sem.post();
// feign hard work for 30s
boost::this_thread::sleep_for(boost::chrono::seconds(30));
if (sem.try_wait())
{
sem.remove("ffed38bd-f0fc-4f79-8838-5301c328268c");
}
}
}
If you start one copy in the back ground, new copies will "refuse" to start ("Oops, second instance") for about 30s.
I have a feeling it might be easier to reverse the logic here. Mmm. Lemme try.
some time passes
Hehe. That was more tricky than I thought.
The thing is, you want to make sure that the lock doesn't remain when your application is interrupted or killed. In the interest of sharing the techniques for portably handling the signals:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread.hpp>
#include <cassert>
#include <boost/asio.hpp>
#define MAX_PROCESS_INSTANCES 3
boost::interprocess::named_semaphore sem(
boost::interprocess::open_or_create,
"4de7ddfe-2bd5-428f-b74d-080970f980be",
MAX_PROCESS_INSTANCES);
// to handle signals:
boost::asio::io_service service;
boost::asio::signal_set sig(service);
int main()
{
if (sem.try_wait())
{
sig.add(SIGINT);
sig.add(SIGTERM);
sig.add(SIGABRT);
sig.async_wait([](boost::system::error_code,int sig){
std::cerr << "Exiting with signal " << sig << "...\n";
sem.post();
});
boost::thread sig_listener([&] { service.run(); });
boost::this_thread::sleep_for(boost::chrono::seconds(3));
service.post([&] { sig.cancel(); });
sig_listener.join();
}
else
{
std::cout << "More than " << MAX_PROCESS_INSTANCES << " instances not allowed\n";
}
}
There's a lot that could be explained there. Let me know if you're interested.
NOTE It should be quite obvious that if kill -9 is used on your application (forced termination) then all bets are off and you'll have to either remove the Name Semaphore object or explicitly unlock it (post()).
Here's a testrun on my system:
sehe#desktop:/tmp$ (for a in {1..6}; do ./test& done; time wait)
More than 3 instances not allowed
More than 3 instances not allowed
More than 3 instances not allowed
Exiting with signal 0...
Exiting with signal 0...
Exiting with signal 0...
real 0m3.005s
user 0m0.013s
sys 0m0.012s
Here's a simplistic way to implement your own 'semaphore' (since I don't think the standard library or boost have one). This chooses a 'cooperative' approach and workers will wait for each other:
#include <boost/thread.hpp>
#include <boost/phoenix.hpp>
using namespace boost;
using namespace boost::phoenix::arg_names;
void the_work(int id)
{
static int running = 0;
std::cout << "worker " << id << " entered (" << running << " running)\n";
static mutex mx;
static condition_variable cv;
// synchronize here, waiting until we can begin work
{
unique_lock<mutex> lk(mx);
cv.wait(lk, phoenix::cref(running) < 3);
running += 1;
}
std::cout << "worker " << id << " start work\n";
this_thread::sleep_for(chrono::seconds(2));
std::cout << "worker " << id << " done\n";
// signal one other worker, if waiting
{
lock_guard<mutex> lk(mx);
running -= 1;
cv.notify_one();
}
}
int main()
{
thread_group pool;
for (int i = 0; i < 10; ++i)
pool.create_thread(bind(the_work, i));
pool.join_all();
}
Now, I'd say it's probably better to have a dedicated pool of n workers taking their work from a queue in turns:
#include <boost/thread.hpp>
#include <boost/phoenix.hpp>
#include <boost/optional.hpp>
using namespace boost;
using namespace boost::phoenix::arg_names;
class thread_pool
{
private:
mutex mx;
condition_variable cv;
typedef function<void()> job_t;
std::deque<job_t> _queue;
thread_group pool;
boost::atomic_bool shutdown;
static void worker_thread(thread_pool& q)
{
while (auto job = q.dequeue())
(*job)();
}
public:
thread_pool() : shutdown(false) {
for (unsigned i = 0; i < boost::thread::hardware_concurrency(); ++i)
pool.create_thread(bind(worker_thread, ref(*this)));
}
void enqueue(job_t job)
{
lock_guard<mutex> lk(mx);
_queue.push_back(std::move(job));
cv.notify_one();
}
optional<job_t> dequeue()
{
unique_lock<mutex> lk(mx);
namespace phx = boost::phoenix;
cv.wait(lk, phx::ref(shutdown) || !phx::empty(phx::ref(_queue)));
if (_queue.empty())
return none;
auto job = std::move(_queue.front());
_queue.pop_front();
return std::move(job);
}
~thread_pool()
{
shutdown = true;
{
lock_guard<mutex> lk(mx);
cv.notify_all();
}
pool.join_all();
}
};
void the_work(int id)
{
std::cout << "worker " << id << " entered\n";
// no more synchronization; the pool size determines max concurrency
std::cout << "worker " << id << " start work\n";
this_thread::sleep_for(chrono::seconds(2));
std::cout << "worker " << id << " done\n";
}
int main()
{
thread_pool pool; // uses 1 thread per core
for (int i = 0; i < 10; ++i)
pool.enqueue(bind(the_work, i));
}
PS. You can use C++11 lambdas instead boost::phoenix there if you prefer.
How can I wake up a QThread when it is sleeping?
I have a thread that is running in the background and now and then wakes up and does some small stuff, however if I would like to stop that thread in a controlled manner I have to wait for him to wake up by him self in order to make him quit. And since he is sleeping quite long this can be quite annoying.
Here is a little example code that show the basic problem.
Let's start with the thread that in this example sleeps for 5 seconds and then just prints a dot.
#include <QDebug>
#include "TestThread.h"
void TestThread::run()
{
running = true;
while(running == true)
{
qDebug() << ".";
QThread::sleep(5);
}
qDebug() << "Exit";
}
void TestThread::stop()
{
running = false;
}
Then we have the main that starts the thread and then kills him.
#include <QDebug>
#include "TestThread.h"
int main(int argc, char *argv[])
{
qDebug() << "Start test:";
TestThread *tt = new TestThread();
tt->start();
sleep(2);
tt->stop();
tt->wait();
delete tt;
}
The problem is that the tt->wait(); must wait the 5s that the thread is sleeping.
Can I just call something like a "wakeup from sleep" so he can continue.
Or is there a better way to do this?
/Thanks
Update I got it working with a QMutex and the tryLock:
#include <QDebug>
#include "TestThread.h"
QMutex sleepMutex;
void TestThread::run()
{
qDebug() << "Begin";
//1. Start to lock
sleepMutex.lock();
//2. Then since it is locked, we can't lock it again
// so we timeout now and then.
while( !sleepMutex.tryLock(5000) )
{
qDebug() << ".";
}
//4. And then we cleanup and unlock the lock from tryLock.
sleepMutex.unlock();
qDebug() << "Exit";
}
void TestThread::stop()
{
//3. Then we unlock and allow the tryLock
// to lock it and doing so return true to the while
// so it stops.
sleepMutex.unlock();
}
But would it be better to use the QWaitCondition? Or is it the same?
Update: The QMutex breaks if it is not the same tread that starts and stop him,
so here is a try with QWaitCondition.
#include <QDebug>
#include <QWaitCondition>
#include "TestThread.h"
QMutex sleepMutex;
void TestThread::run()
{
qDebug() << "Begin";
running = true;
sleepMutex.lock();
while( !waitcondition.wait(&sleepMutex, 5000) && running == true )
{
qDebug() << ".";
}
qDebug() << "Exit";
}
void TestThread::stop()
{
running = false;
waitcondition.wakeAll();
}
You could use a QWaitCondition rather than a simple sleep. If gives you much more control.
Example usage here: Wait Conditions Example
I don't think that a portable solution exists (though there might be some facilities in some operation systems, like POSIX signals). Anyway, Qt itself doesn't provide such means, thus you could simulate it like
void TestThread::run()
{
running = true;
while(running == true)
{
qDebug() << ".";
// Quantize the sleep:
for (int i = 0; i < 5 && running; ++i) QThread::sleep(1);
}
qDebug() << "Exit";
}
But the best solution would still be a QWaitCondition, as pointed out by Mat.