Reputation: 143
I need to start a loop from an event and then stop it from another event. My idea was to call the function startDequeuing() when I press the button so that a thread with the loop start and then to terminate this loop putting "dequeuing" variable at false from the function stopDequeuing().
It's the first time I use thread, the program locks when I start the loop I think because the variable 'dequeuing' is locked and inaccessible from outside the thread, am I correct?
How can I solve this problem??
Here there is some code:
void CameraManager::startDequeuing(){
dequeuing = true;
std::thread dequeueThread(&CameraManager::dequeueLoop, this);
dequeueThread.join();
}
void CameraManager::stopDequeuing(){
dequeuing = false;
}
void *CameraManager::dequeueLoop(){
while(dequeuing){
highSpeedCamera->dequeue();
highSpeedCamera->enqueue();
}
}
Upvotes: 2
Views: 6939
Reputation: 76295
Define dequeing
as an atomic bool:
#include <atomic>
std::atomic_bool dequeing = false;
It's much faster than using a mutex and gets you the same synchronization.
Upvotes: 3
Reputation: 2555
The whole point of using threads is to get more than one function running in parallel. Here:
std::thread dequeueThread(&CameraManager::dequeueLoop, this);
dequeueThread.join();
You start a second thread and put the first thread to sleep, waiting for the spawned thread to return. So you still have just one thread running. If you have so kind of GUI event loop, you might lock for a possibility to add a callback that will get called, when ever that event loop is empty. This might enable you to do what you want without using threads at all.
A solution might look like this:
void CameraManager::startDequeuing(){
dequeuing = true;
dequeueThread = std::thread(&CameraManager::dequeueLoop, this);
}
void CameraManager::stopDequeuing(){
{
std::lock_guard<std::mutex> lock( mutex );
dequeuing = false;
}
dequeueThread.join();
}
bool CameraManager::keepOnDequeuing()
{
std::lock_guard<std::mutex> lock( mutex );
return dequeuing;
}
void *CameraManager::dequeueLoop(){
while( keepOnDequeuing() ){
highSpeedCamera->dequeue();
highSpeedCamera->enqueue();
}
}
Upvotes: 3
Reputation: 28178
Your program deadlocks because join()
will block until your thread function completes; And it will never complete at that point because it's effectively executing while(true)
.
You want dequeueThread
to be a member of your class. Why would you want it to survive only for the scope of startDequeuing
?
Upvotes: 3