I have a program, where there are multiple threads running in an infinite loop. Each thread can handling a certain number of tasks say MAXTASKFOREACHTHREAD. A new thread is generated when the number of tasks increases. If MAXTASKFOREACHTHREAD is not reached, new task will be added into it. But if the task is completed such that number of task in a thread = 0, at a particular point. I want to terminate that thread. I don't want that thread to keep waiting for a task. A new thread can be spawned as needed.
class ThreadPool
{
void createThread();
static void threadFunc(ThreadPool *);
private:
thread t;
int val = 0;
}
void ThreadPool::createThread()
{
t = thread(threadFunc, this);
}
void ThreadPool::threadFunc();
//carries the function implementation regarding tasks
int main()
{
vector<ThreadPool *> v;
v.push_back(new ThreadPool());
v.push_back(new ThreadPool());
v.push_back(new ThreadPool());
v[0].createThread();
v[1].createThread();
v[2].createThread();
}
// Code might have syntax error, I just typed out!
// Now how should I proceed with the deletion of thread, without causing memory corruption!, I need to delete the corresponing object, of the thread
// I am looking for a idea, how to deal with this, without increasing the complexity by using locks.
Please give some suggestions!
If any part is not clear that add in comments.
It seems that you're forgetting that threads run code. You can simply use the worker thread itself to check if there's more work.
First, let's clear up some confusion. A ThreadPool holds multiple threads. In your case, v would be that pool. std::vector is not really a convenient interface for that. So, rename your existing ThreadPool to WorkerThread, and create a ThreadPool with a private: std::vector<WorkerThread>. (objects, not pointers)
The WorkerThread cooperates with ThreadPool. Your WorkerThread::threadFunc has a main loop that checks if there is work. If so, it's executed. But if there's no work, that's the case where you retire the thread. You exit the thread main loop, tell the ThreadPool you're done, and let it call join. Alternatively, detach the WorkerThreads.
Another way to remove threads is to make a special task in the ThreadPool, which causes the WorkerThread which picks it up to exit its main loop. This could be implemented as an empty std::function<>, for instance. In this way, you can actively reduce the number of threads, even if there is work left.
Related
In C++ I have an std::vector of threads, each running a function running forever [while(true)].
I'm joining them in a for loop:
for (auto& thread : threads)
{
thread.join();
}
When the program finishes I'm getting a std::terminate() call inside the destructor of one of the threads. I think I understand why that happens, except for the first thread the other join calls don't get called.
What is the correct way of joining those threads?
And is it actually necessary to join them? (assuming they are not supposed to join under normal circumstances)
If the threads cannot be joined because they never exit then you could use std::thread::detach (https://en.cppreference.com/w/cpp/thread/thread/detach). Either way before joining you should always check std::thread::joinable (https://en.cppreference.com/w/cpp/thread/thread/joinable).
The std::terminate is indeed most likely due to a running thread being destroyed and not being detached or joined before that. Note however that what happens to detached threads on application exit is implementation defined. If possible you should probably change the logic in those threads to allow graceful exit (std::jthread or std::atomic could help make stoppable threads):
EDIT:
Semi-complete C++17 "correct" code:
std::atomic stop{false};
std::vector<std::thread> threads;
threads.emplace_back(std::thread{[&] { while (!stop.load()) { /* */ }}});
threads.emplace_back(std::thread{[&] { while (!stop.load()) { /* */ }}});
//...
stop.store(true);
for (auto& thread : threads)
{
if (thread.joinable())
{
thread.join();
}
}
Semi-complete C++20 "correct" code:
std::vector<std::jthread> threads;
threads.emplace_back(std::jthread{[] (std::stop_token stopToken) { while (!stopToken.stop_requested()) { /* */ }}});
threads.emplace_back(std::jthread{[] (std::stop_token stopToken) { while (!stopToken.stop_requested()) { /* */ }}});
The C++20 std::jthread allows functions that take std::stop_token to receive a signal to stop. The destructor std::~jthread() first requests stop via the token and then joins so in the above setup basically no manual cleanup is necessary. Unfortunately only MSVC STL and libstdc++ currently support it while Clang's libc++ does not. But it is easy enough to implement yourself atop of std::thread if you'd fancy a bit of exercise.
What is the correct way of joining those threads?
Your way is fine, depending on what you're trying to do.
And is it actually necessary to join them?
Yes. And no.
See, the main issue with std::thread is that you need to clean them up or they'll "do bad things" (TM), but joining them is only one way of cleaning them up. The other way is to simply detach them from your actual threads, if you don't care to control them anymore (which seems to be the case?).
The things you need to ask yourself is if your setup makes sense, where you create a whole bunch of threads that don't end cleanly but instead are interrupted randomly by your entire process dying. What happens to the work they were supposed to do? If they write their output somewhere and it's interrupted half way through, are you, your employers and your customers okay with file corruption?
Due to fixed requirements, I need to execute some code in a specific thread, and then return a result. The main-thread initiating that action should be blocked in the meantime.
void background_thread()
{
while(1)
{
request.lock();
g_lambda();
response.unlock();
request.unlock();
}
}
void mainthread()
{
...
g_lambda = []()...;
request.unlock();
response.lock();
request.lock();
...
}
This should work. But it leaves us with a big problem: background thread needs to start with response mutex locked, and main-thread needs to start with request mutex locked...
How can we accomplish that? I cant think of a good way. And isnt that an anti-pattern anyways?
Passing tasks to background thread could be accomplished by a producer-consumer queue. Simple C++11 implementation, that does not depend on 3rd party libraries would have std::condition_variable which is waited by the background thread and notified by main thead, std::queue of tasks, and std::mutex to guard these.
Getting the result back to main thread can be done by std::promise/std::future. The simplest way is to make std::packaged_task as queue objects, so that main thread creates packaged_task, puts it to the queue, notifies condition_variable and waits on packaged_task's future.
You would not actually need std::queue if you will create tasks by one at once, from one thread - just one std::unique_ptr<std::packaged_task>> would be enough. The queue adds flexibility to simultaneosly add many backround tasks.
If I have a Qt application (that uses QCoreApplication), and this application starts a few permanent threads, what is the proper way to shut down the application?
Is it alright to just run QCoreApplication::quit() in one of the threads? Will this cause the other threads to be gracefully terminated (and have all their contained objects' destructors called, as opposed to being forcefully killed)?
Further details to explain the nature of the threads: they are predefined and run from startup and do not stop until the application exits, i.e. they're permanent. They run their own event loop and communicate with other threads via signals and slots. These are normal threading, not task-based concurrency.
Most long running 'thread main' functions have a form a bit like the following:
while (doWork) {
work();
}
with doWork being a std::atomic<bool>.
When the main thread wants to quit, it sets myThread.doWork = false on all the threads that are still alive, which allows them to fall out when they're ready.
By calling myThread.wait() on the main thread, it blocks until the thread that you've told to stop doing work actually stops.
In doing this for all your threads, by the time the main thread leaves main() it's the only thread still running.
Side note:
if you have to await work to be pushed to it, you probably want to look into the QWaitCondition class so that you can awake your thread both when there's work and when you want it to stop.
It highly depends on how you use the threads.
If you use them as seperate eventloops, and not as "worker threads", simply stop the by quitting the threads from the QCoreApplication::aboutToQuit signal:
QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, [thread](){
thread->quit();
thread->wait(1000);
});
(For multiple threads, first quit all of them and then wait)
In case you use them as real workerthreads, where you do permanent work in a loop etc, you can use QThreads interruptions mechanism. In your thread do:
while(!QThread::currentThread()->isInterruptionRequested()) {
// code...
}
and quit them in a very similar way:
QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, [thread](){
thread->requestInterruption();
thread->wait(1000);
});
Most modern platforms will aim to 'clean up' after processes end abruptly.
That is end all the threads, recover all the memory, close any open files and recover any other resources or handles allocated to a process.
But it not recommended that is relied on and when execution may have 'durable' side-effects such as writing to files or communicating with other processes (including sharing memory) that may survive termination it may not be possible to clean up easily. Files could remain half written and other processes may receive half complete messages or send messages to processes that didn't declare termination.
It's also very hard to identify memory leaks in processes that are ended abruptly.
Best practice is always going to bring all threads to a known conclusion.
The recommended way to terminate is to define one or more stop flags (often bool) that will be checked by threads at 'safe' points to terminate.
Those stop flags should be atomic (std::atomic<>) or protected by a std::mutex if used in a wait() condition.
In that model termination code could look something like..
#include <iostream>
#include <atomic>
#include <mutex>
#include <thread>
#include <vector>
std::atomic<bool> stop_flag;
std::vector<std::thread> threads;
std::mutex cout_mutex;//std::cout is not natively synchronized.
void chug(size_t index){
int i{0};
while(!stop_flag){
{
std::lock_guard<std::mutex> guard{cout_mutex};
std::cout<<index<<" : "<<i<<std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));//slow it down!
++i;
}
}
//stop_all brings all the threads to a safe and known conclusion.
void stop_all(){
stop_flag=true;
for( auto& curr: threads){
curr.join();
}
}
int main() {
const size_t num{10};
for(size_t i=0;i<num;++i){
threads.emplace_back(chug,i);
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));//Let it run!
stop_all();
return 0;
}
With the author of question explanation we can narrow down to exact type of threads:
I have predefined threads that run from startup and do not stop until
the application exits, i.e. they're permanent. They run their own
event loop and communicate with other threads via signals and slots.
These are normal threading, not task-based concurrency. How can I
organize this type of multi-threading?
It is quite easy to organize in Qt by "moving" the object with predefined signals and slots to the thread in which its methods supposed to run in.
class Worker : public QObject
{
Q_OBJECT
public:
Worker(Load*);
signals:
void produce(Result*);
public slots:
void doWork(Load*);
};
void Worker::doWork(Load* pLoad)
{
// here we can check if thread interruption is requested
// if the work is of iterative long time type
while(!QThread::currentThread()->isInterruptionRequested())
{
process(pLoad);
if (pLoad->finished())
{
emit produce(pLoad->result()); // deliver the result
return; // back to worker thread event loop to wait
}
}
// interrupted before the load finished
QThread::currentThread()->quit();
}
// { somewhere on the main thread
// main thread launches worker threads like this one
QThread thread;
Worker worker(new Load());
worker.moveToThread(&thread); // the worker will be leaving in the thread
// start!
thread.start();
// worker thread adds new workload on its thread
// through the thread event loop by invokeMethod
QMetaObject::invokeMethod(&worker, "doWork", Qt::AutoConnection,
Q_ARG(Load*, new Load));
// after all we want to quit the app
thread.requestInterruption(); // for faster finishing
// or
thread.quit(); // for finishing after the last data processed
thread.wait(); // for one thread wait but you can catch finished()
// signals from many threads (say, count until all signaled)
// ........
// quit the app
// ........
qApp->quit();
// } somewhere on main thread
It may look a bit like task-based concurrency but there is no task object on thread picking up its load from the queue. It just demonstrates Qt work thread communicating via signals and slots.
I agree #UKMonkey idea for a thread block but if some threads are waiting for a device or a memory and condition waits that dose not guaranteed thread quit and even it's prevent application quit.
so what to do for those situations , QCoreApplication has aboutToQuit() signal you can connect it to a slot and force your threads to quit and check if a thread don't quit gracefully and correct it's quit scenario.
I have the following code:
void do_join(std::thread& t)
{
t.join();
}
void join_all(std::vector<std::thread>& v)
{
std::for_each(v.begin(),v.end(),do_join);
}
int main()
{
std::vector<std::thread> myThreads;
for(int i = 1; i <= 3; i++)
{
myThreads.push_back(std::thread(threadMethod));
}
join_all(myThreads);
}
The goal is to create multiple threads in a loop, add them to a thread vector and then iterating through the vector join them to the main thread.
The problem here is that when my do_join method executes for the first time it joins the thread and waits, not joining any other threads from a vector. That is because my threads are using some conditional variables and waiting for some other tasks to complete. Seems like that do_join method is waiting for just joined thread to complete.
The same thing happens if I try to do for_each directly in the main function.
The idea is to be able to join all these threads to the main thread, not to that let's say do_join's method thread which I suppose happened here. I could of course join and create them separately, because actually I don't need them to be in a vector (the number of threads is known from the beginning), but I need a vector because each thread in my application is actually created using different method's parameters which I did not included in that sample code. I just do not want a new line for every single thread being created and joined.
Thank you for any help!
Edit:
Maybe worth mentioning is that I'm using Ubuntu.
The join method by definition blocks current thread until the one you are trying to join is done:
Blocks the current thread until the thread identified by *this
finishes its execution.
(From here.)
That is, it’s the purpose of join to block its thread until the other one finishes. If you don’t want the thread to be blocked, then don’t use join.
You should ask yourself the question: what are you trying to achieve? If you want your main program to proceed only when all the other threads are done, then what you are doing now is right, you’ll have to wait for all the threads anyway. Otherwise you might need some way for other threads to signal the main one that they are done.
I'm reading that I should use worker object and move it to thread by moveToThread instead of inherit from QThread directly. But I can't find solution how to stop loop in my object worker. For example I have test loop:
void CollectionWorker::doWork()
{
for (int i = 0; i < 10; ++i) {
sleep(1);
emit ping(i);
}
}
Now I'm moving this object to thread:
worker->moveToThread(mTh);
This is working fine. But when I call mTh.quit() then thread is waiting until loop in doWork is end. When I inherit from QThread directly then on each loop I can check thread status and break loop when thred is finished but don't know how to do it in worker object. Can I just create some flag in worker object and switch it from main thread? Or maybe can I find thread owner and check it status? Or maybe better before starting thread, set thread pointer in worker object and then check status? What is the best thread safe solution?
Regards
Calling quit() or exit() on a thread object will simply end the event loop of the thread if there is any running. But As you rightly pointed out, the original problem remains the same. What if the worker function has already been executed by event loop and is a long running function with forever construct. The call to quit() or exit() will simply wait till the worker function returns.
Couple of approaches can be suggested apart from making a public function available to caller which will alter an internal flag.
Give a termination signal and slot in your worker class. Something as following.
signals:
void signalTermination();
public slots:
void setTerminationFlag();
private:
QMutex mutex;
bool terminationRequested;
Your slot would look like something.
void setTerminationFlag()
{
QMutexLocker locker(&mutex);
terminationRequested = true;
}
Then you can check the variable in your doWork function in every iteration of forever loop.
mutex.lock();
if(terminationRequested)
{
//break from loop and effectively doWork function
}
mutex.unlock();
One of the reason of using signals and slots instead of plain member function is that, if your worker function is doing some long running task inside synchronized code block, the public function will remain blocked until it gets access of the synchronization object. This might have adverse effect if the calling thread of your public termination method is UI thread.
Another clean and simpler approach if you are using Qt 5.2 onwards
Use requestInterruption() method of QThread. This method sets an advisory flag in the thread object which you can check via isInterruptionRequested() function call in your doWork() function. See following code snippet given in QThread::isInterruptionRequested documentation.
void long_task() {
forever {
if ( QThread::currentThread()->isInterruptionRequested() ) {
return;
}
}
}
You can also directly call quit() here to end the event loop of the thread.
Edit: Sorry i've misunderstood your question.
There are several alternatives. You can create some flag and before each iteration of your processing loop you check if the flag has been set. Or, in the case your processing data in a list/queue maybe you could signal the process to terminate with a special end-of-data element.
I have the same problem as Dibo had. I'm running a long calculation loop inside my doWork() function and need to be able to stop it from my main thread.
Chadick Robbert's answers didn't do the trick for me. The first suggestion behaved just like what he describes for member functions. That is, although we're using signals and slots, calling setTerminationFlag slot from a signal emitted in the main thread, properly connected to it, only gets executed after the loop ends. But maybe I did something wrong with the implementation. If it really is supposed to work please let me know, because it seems like the deal breaker.
His second alternative of using QThread::currentThread()->isInterruptionRequested() to tell the thread to stop would work great if it weren't for the fact that you can't reset this flag if you plan on reusing the thread and worker for some similar processing intensive loop, if not the same. Surely you can get it done by stopping and starting the thread, but I'm not sure if it wouldn't have adverse effects like clearing execution queues on it. This issue was actually posted as a bug report and Thiago Macieira (key developer for Qt) mentions there, if I may quote him:
The purpose of the requestInterruption function is to finish the thread.
Which makes requestInterruption inadequate for the job, as it is reset only on thread start and finish.
A solution that I found, that doesn't seem all that clean to me, is to include QCoreApplication in the worker class and call QCoreApplicaton::processEvents() from time to time, to process those queued signals in Chadick Robbert's first suggestion or update the worker's class awareness of flag variables shared between threads.
Because calling QCoreApplicaton::processEvents() within your loop can slow it dramatically what I do is something like:
for(unsigned long int i=0; i<800000000 && !*stop; i++){
f += (double)i * .001; // dummy calculation
if(i%10000000 == 0) // Call it only from time to time
QCoreApplication::processEvents(); // update *stop according to main Thread
}
As you can see, with this solution the loop will only break at integer multiples of '10000000' which may not be adequate for some use cases.
If anyone knows of a killer solution to this I'd love to hear.
The idiomatic way in Qt to destroy a worker thread is using the signal/slot interface:
CollectionWorker *worker = new CollectionWorker;
QThread *workerThread = new QThread(this);
connect(workerThread, SIGNAL(started()), worker, SLOT(doWork()));
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
worker->moveToThread(workerThread);
In order for this to work CollectionWorker must inherit from a QObject class and declare the Q_OBJECT macro.