How to say to std::thread to stop? - c++

I have two questions.
1) I want to launch some function with an infinite loop to work like a server and checking for messages in a separate thread. However I want to close it from the parent thread when I want. I'm confusing how to std::future or std::condition_variable in this case. Or is it better to create some global variable and change it to true/false from the parent thread.
2) I'd like to have something like this. Why this one example crashes during the run time?
#include <iostream>
#include <chrono>
#include <thread>
#include <future>
std::mutex mu;
bool stopServer = false;
bool serverFunction()
{
while (true)
{
// checking for messages...
// processing messages
std::this_thread::sleep_for(std::chrono::seconds(1));
mu.lock();
if (stopServer)
break;
mu.unlock();
}
std::cout << "Exiting func..." << std::endl;
return true;
}
int main()
{
std::thread serverThread(serverFunction);
// some stuff
system("pause");
mu.lock();
stopServer = true;
mu.unlock();
serverThread.join();
}

Why this one example crashes during the run time?
When you leave the inner loop of your thread, you leave the mutex locked, so the parent thread may be blocked forever if you use that mutex again.
You should use std::unique_lock or something similar to avoid problems like that.

You leave your mutex locked. Don't lock mutexes manually in 999/1000 cases.
In this case, you can use std::unique_lock<std::mutex> to create a RAII lock-holder that will avoid this problem. Simply create it in a scope, and have the lock area end at the end of the scope.
{
std::unique_lock<std::mutex> lock(mu);
stopServer = true;
}
in main and
{
std::unique_lock<std::mutex> lock(mu);
if (stopServer)
break;
}
in serverFunction.
Now in this case your mutex is pointless. Remove it. Replace bool stopServer with std::atomic<bool> stopServer, and remove all references to mutex and mu from your code.
An atomic variable can safely be read/written to from different threads.
However, your code is still busy-waiting. The right way to handle a server processing messages is a condition variable guarding the message queue. You then stop it by front-queuing a stop server message (or a flag) in the message queue.
This results in a server thread that doesn't wake up and pointlessly spin nearly as often. Instead, it blocks on the condition variable (with some spurious wakeups, but rare) and only really wakes up when there are new messages or it is told to shut down.
template<class T>
struct cross_thread_queue {
void push( T t ) {
{
auto l = lock();
data.push_back(std::move(t));
}
cv.notify_one();
}
boost::optional<T> pop() {
auto l = lock();
cv.wait( l, [&]{ return halt || !data.empty(); } );
if (halt) return {};
T r = data.front();
data.pop_front();
return std::move(r); // returning to optional<T>, so we'll explicitly `move` here.
}
void terminate() {
{
auto l = lock();
data.clear();
halt = true;
}
cv.notify_all();
}
private:
std::mutex m;
std::unique_lock<std::mutex> lock() {
return std::unique_lock<std::mutex>(m);
}
bool halt = false;
std::deque<T> data;
std::condition_variable cv;
};
We use boost::optional for the return type of pop -- if the queue is halted, pop returns an empty optional. Otherwise, it blocks until there is data.
You can replace this with anything optional-like, even a std::pair<bool, T> where the first element says if there is anything to return, or a std::unique_ptr<T>, or a std::experimental::optional, or a myriad of other choices.
cross_thread_queue<int> queue;
bool serverFunction()
{
while (auto message = queue.pop()) {
// processing *message
std::cout << "Processing " << *message << std::endl;
}
std::cout << "Exiting func..." << std::endl;
return true;
}
int main()
{
std::thread serverThread(serverFunction);
// some stuff
queue.push(42);
system("pause");
queue.terminate();
serverThread.join();
}
live example.

Related

Correct way to check bool flag in thread

How can I check bool variable in class considering thread safe?
For example in my code:
// test.h
class Test {
void threadFunc_run();
void change(bool _set) { m_flag = _set; }
...
bool m_flag;
};
// test.cpp
void Test::threadFunc_run()
{
// called "Playing"
while(m_flag == true) {
for(int i = 0; i < 99999999 && m_flag; i++) {
// do something .. 1
}
for(int i = 0; i < 111111111 && m_flag; i++) {
// do something .. 2
}
}
}
I wan to stop "Playing" as soon as change(..) function is executed in the external code.
It also wants to be valid in process of operating the for statement.
According to the search, there are variables for recognizing immediate changes, such as atomic or volatile.
If not immediately, is there a better way to use a normal bool?
Actually synchronizing threads safely requires more then a bool.
You will need a state, a mutex and a condition variable like this.
The approach also allows for quick reaction to stop from within the loop.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <future>
#include <mutex>
class Test
{
private:
// having just a bool to check the state of your thread is NOT enough.
// your thread will have some intermediate states as well
enum play_state_t
{
idle, // initial state, not started yet (not scheduled by OS threadscheduler yet)
playing, // running and doing work
stopping, // request for stop is issued
stopped // thread has stopped (could also be checked by std::future synchronization).
};
public:
void play()
{
// start the play loop, the lambda is not guaranteed to have started
// after the call returns (depends on threadscheduling of the underlying OS)
// I use std::async since that has far superior synchronization with the calling thead
// the returned future can be used to pass both values & exceptions back to it.
m_play_future = std::async(std::launch::async, [this]
{
// give a signal the asynchronous function has really started
set_state(play_state_t::playing);
std::cout << "play started\n";
// as long as state is playing keep doing the work
while (get_state() == play_state_t::playing)
{
// loop to show we can break fast out of it when stop is called
for (std::size_t i = 0; (i < 100l) && (get_state() == play_state_t::playing); ++i)
{
std::cout << ".";
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
set_state(play_state_t::stopped);
std::cout << "play stopped.\n";
});
// avoid race conditions really wait for
// trhead handling async to have started playing
wait_for_state(play_state_t::playing);
}
void stop()
{
std::unique_lock<std::mutex> lock{ m_mtx }; // only wait on condition variable in lock
if (m_state == play_state_t::playing)
{
std::cout << "\nrequest stop.\n";
m_state = play_state_t::stopping;
m_cv.wait(lock, [&] { return m_state == play_state_t::stopped; });
}
};
~Test()
{
stop();
}
private:
void set_state(const play_state_t state)
{
std::unique_lock<std::mutex> lock{ m_mtx }; // only wait on condition variable in lock
m_state = state;
m_cv.notify_all(); // let other threads that are wating on condition variable wakeup to check new state
}
play_state_t get_state() const
{
std::unique_lock<std::mutex> lock{ m_mtx }; // only wait on condition variable in lock
return m_state;
}
void wait_for_state(const play_state_t state)
{
std::unique_lock<std::mutex> lock{ m_mtx };
m_cv.wait(lock, [&] { return m_state == state; });
}
// for more info on condition variables
// see : https://www.modernescpp.com/index.php/c-core-guidelines-be-aware-of-the-traps-of-condition-variables
mutable std::mutex m_mtx;
std::condition_variable m_cv; // a condition variable is not really a variable more a signal to threads to wakeup
play_state_t m_state{ play_state_t::idle };
std::future<void> m_play_future;
};
int main()
{
Test test;
test.play();
std::this_thread::sleep_for(std::chrono::seconds(1));
test.stop();
return 0;
}

Threading queue in c++

Currently working on a project, im struggeling with threading and queue at the moment, the issue is that all threads take the same item in the queue.
Reproduceable example:
#include <iostream>
#include <queue>
#include <thread>
using namespace std;
void Test(queue<string> queue){
while (!queue.empty()) {
string proxy = queue.front();
cout << proxy << "\n";
queue.pop();
}
}
int main()
{
queue<string> queue;
queue.push("101.132.186.39:9090");
queue.push("95.85.24.83:8118");
queue.push("185.211.193.162:8080");
queue.push("87.106.37.89:8888");
queue.push("159.203.61.169:8080");
std::vector<std::thread> ThreadVector;
for (int i = 0; i <= 10; i++){
ThreadVector.emplace_back([&]() {Test(queue); });
}
for (auto& t : ThreadVector){
t.join();
}
ThreadVector.clear();
return 0;
}
You are giving each thread its own copy of the queue. I imagine that what you want is all the threads to work on the same queue and for that you will need to use some synchronization mechanism when multiple threads work on the shared queue as std queue is not thread safe.
edit: minor note: in your code you are spawning 11 threads not 10.
edit 2: OK, try this one to begin with:
std::mutex lock_work;
std::mutex lock_io;
void Test(queue<string>& queue){
while (!queue.empty()) {
string proxy;
{
std::lock_guard<std::mutex> lock(lock_work);
proxy = queue.front();
queue.pop();
}
{
std::lock_guard<std::mutex> lock(lock_io);
cout << proxy << "\n";
}
}
}
Look at this snippet:
void Test(std::queue<std::string> queue) { /* ... */ }
Here you pass a copy of the queue object to the thread.
This copy is local to each thread, so it gets destroyed after every thread exits so in the end your program does not have any effect on the actual queue object that resides in the main() function.
To fix this, you need to either make the parameter take a reference or a pointer:
void Test(std::queue<std::string>& queue) { /* ... */ }
This makes the parameter directly refer to the queue object present inside main() instead of creating a copy.
Now, the above code is still not correct since queue is prone to data-race and neither std::queue nor std::cout is thread-safe and can get interrupted by another thread while currently being accessed by one. To prevent this, use a std::mutex:
// ...
#include <mutex>
// ...
// The mutex protects the 'queue' object from being subjected to data-race amongst different threads
// Additionally 'io_mut' is used to protect the streaming operations done with 'std::cout'
std::mutex mut, io_mut;
void Test(std::queue<std::string>& queue) {
std::queue<std::string> tmp;
{
// Swap the actual object with a local temporary object while being protected by the mutex
std::lock_guard<std::mutex> lock(mut);
std::swap(tmp, queue);
}
while (!tmp.empty()) {
std::string proxy = tmp.front();
{
// Call to 'std::cout' needs to be synchronized
std::lock_guard<std::mutex> lock(io_mut);
std::cout << proxy << "\n";
}
tmp.pop();
}
}
This synchronizes each thread call and prevents access from any other threads while queue is still being accessed by a thread.
Edit:
Alternatively, it'd be much faster in my opinion to make each thread wait until one of them receives a notification of your push to std::queue. You can do this through the use of std::condition_variable:
// ...
#include <mutex>
#include <condition_variable>
// ...
std::mutex mut1, mut2;
std::condition_variable cond;
void Test(std::queue<std::string>& queue, std::chrono::milliseconds timeout = std::chrono::milliseconds{10}) {
std::unique_lock<std::mutex> lock(mut1);
// Wait until 'queue' is not empty...
cond.wait(lock, [queue] { return queue.empty(); });
while (!queue.empty()) {
std::string proxy = std::move(queue.front());
std::cout << proxy << "\n";
queue.pop();
}
}
// ...
int main() {
std::queue<string> queue;
std::vector<std::thread> ThreadVector;
for (int i = 0; i <= 10; i++)
ThreadVector.emplace_back([&]() { Test(queue); });
// Notify the vectors of each 'push()' call to 'queue'
{
std::unique_lock<std::mutex> lock(mut2);
queue.push("101.132.186.39:9090");
cond.notify_one();
}
{
std::unique_lock<std::mutex> lock(mut2);
queue.push("95.85.24.83:8118");
cond.notify_one();
}
{
std::unique_lock<std::mutex> lock(mut2);
queue.push("185.211.193.162:8080");
cond.notify_one();
}
{
std::unique_lock<std::mutex> lock(mut2);
queue.push("87.106.37.89:8888");
cond.notify_one();
}
{
std::unique_lock<std::mutex> lock(mut2);
queue.push("159.203.61.169:8080");
cond.notify_one();
}
for (auto& t : ThreadVector)
t.join();
ThreadVector.clear();
}

Pause threads from a different thread, and then wait until all are paused

I want to pause a number of worker thread from a creator thread. This can be done with a conditional variable, as seen in this code.
#include <iostream>
#include <vector>
#include <thread>
#include <condition_variable>
#include <atomic>
#define NR_ITERATIONS 3
#define NR_THREADS 5
class c_threads {
private:
bool m_worker_threads_pause;
//std::atomic<int> m_worker_threads_paused;
std::mutex m_worker_thread_mutex;
std::condition_variable m_worker_thread_conditional_variable;
void worker_thread() {
std::unique_lock<std::mutex> worker_thread_lock(m_worker_thread_mutex);
m_worker_thread_conditional_variable.wait(worker_thread_lock,
[this]{return !this->m_worker_threads_pause;}
);
std::cout << "worker thread function" << std::endl;
//...
}
void creator_thread() {
std::cout << "creator thread function" << std::endl;
{
std::lock_guard<std::mutex> lock_guard(m_worker_thread_mutex);
m_worker_threads_pause = true;
}
// wait_until( worker_threads_waiting == NR_THREADS);
//...
{
std::lock_guard<std::mutex> lock_guard(m_worker_thread_mutex);
m_worker_threads_pause = false;
}
m_worker_thread_conditional_variable.notify_all();
}
public:
c_threads() : m_worker_threads_pause(true)
/*m_worker_threads_paused(0)*/ {}
void start_job() {
std::vector<std::thread> worker_threads;
worker_threads.reserve(NR_THREADS);
for (int i=0;i<NR_THREADS;i++) {
worker_threads.emplace_back(&c_threads::worker_thread,this);
}
std::thread o_creator_thread(&c_threads::creator_thread,this);
o_creator_thread.join();
for (auto& thread : worker_threads) {
thread.join();
}
}
};
int main(int argc, char** argv) {
c_threads o_threads;
o_threads.start_job();
}
The problem is that the creator_thread function should wait until all worker_functions are waiting at the conditional variable before it proceeds.
Every time that the creator_thread function is called it should
Pause the worker threads
Wait until they are all paused at the condition variable
Proceed
How to achieve this?
There might be a better way, but I think you're going to have to do something a little more complicated, like create a gatekeeper object. Worker threads generally work like this:
while(iShouldKeepRunning()) {
... lock the mutex
... look for something to do
... if nothing to do, then wait on the condition
}
I think instead you would want some sort of "give me more work" object, or maybe a "is it safe to keep working" object that your creater thread can block.
while(iShouldKeepRunning()) {
... no mutex at all
... ask the gatekeeper for something to do / if it's safe to do something
... and the gatekeeper blocks as necessary
... do the work
}
The gatekeeper locks the mutex, checks if it's safe to give out work, and if it isn't, increments a "I'm making this guy wait" counter before blocking on the condvar.
Something like that.
The blocker might look something like:
class BlockMyThreads {
public:
int runningCount = 0;
int blockedCount = 0;
bool mayWork = true;
std::mutex myMutex;
std::condition_variable condVar;
void iAmWorking() {
std::unique_lock<std::mutex> lock(myMutex);
++runningCount;
}
void letMeWork() {
std::unique_lock<std::mutex> lock(myMutex);
while (!mayWork) {
++blockedCount;
condVar.wait(lock);
--blockedCount;
}
}
void block() {
std::unique_lock<std::mutex> lock(myMutex);
mayWork = false;
}
void release() {
std::unique_lock<std::mutex> lock(myMutex);
mayWork = true;
condVar.notifyAll(lock);
}
};
I haven't tested this, so there might be errors. Your worker threads would need to call iAmWorking() at the start (to give you a thread count) and you'd want to increment a decrement they call when they're done, I suppose.
The main thread can call block() and release() as you desire.

std::thread: How to wait (join) for any of the given threads to complete?

For example, I have two threads, t1 and t2. I want to wait for t1 or t2 to finish. Is this possible?
If I have a series of threads, say, a std::vector<std::thread>, how can I do it?
There's always wait & notify using std::condition_variable, e.g.:
std::mutex m;
std::condition_variable cond;
std::atomic<std::thread::id> val;
auto task = [&] {
std::this_thread::sleep_for(1s); // Some work
val = std::this_thread::get_id();
cond.notify_all();
};
std::thread{task}.detach();
std::thread{task}.detach();
std::thread{task}.detach();
std::unique_lock<std::mutex> lock{m};
cond.wait(lock, [&] { return val != std::thread::id{}; });
std::cout << "Thread " << val << " finished first" << std::endl;
Note: val doesn't necessarily represent the thread that finished first as all threads finish at about the same time and an overwrite might occur, but it is only for the purposes of this example.
No, there is no wait for multiple objects equivalent in C++11's threading library.
If you want to wait on the first of a set of operations, consider having them feed a thread-safe producer-consumer queue.
Here is a post I made containing a threaded_queue<T>. Have the work product of your threads be delivered to such a queue. Have the consumer read off of the other end.
Now someone can wait on (the work product) of multiple threads at once. Or one thread. Or a GPU shader. Or work product being delivered over a RESTful web interface. You don't care.
The threads themselves should be managed by something like a thread pool or other higher level abstraction on top of std::thread, as std::thread makes a poor client-facing threading abstraction.
template<class T>
struct threaded_queue {
using lock = std::unique_lock<std::mutex>;
void push_back( T t ) {
{
lock l(m);
data.push_back(std::move(t));
}
cv.notify_one();
}
boost::optional<T> pop_front() {
lock l(m);
cv.wait(l, [this]{ return abort || !data.empty(); } );
if (abort) return {};
auto r = std::move(data.back());
data.pop_back();
return r;
}
void terminate() {
{
lock l(m);
abort = true;
data.clear();
}
cv.notify_all();
}
~threaded_queue()
{
terminate();
}
private:
std::mutex m;
std::deque<T> data;
std::condition_variable cv;
bool abort = false;
};
I'd use std::optional instead of boost::optional in C++17. It can also be replaced with a unique_ptr, or a number of other constructs.
It's easy to do with a polling wait:
#include<iostream>
#include<thread>
#include<random>
#include<chrono>
#include<atomic>
void thread_task(std::atomic<bool> & boolean) {
std::default_random_engine engine{std::random_device{}()};
std::uniform_int_distribution<int64_t> dist{1000, 3000};
int64_t wait_time = dist(engine);
std::this_thread::sleep_for(std::chrono::milliseconds{wait_time});
std::string line = "Thread slept for " + std::to_string(wait_time) + "ms.\n";
std::cout << line;
boolean.store(true);
}
int main() {
std::vector<std::thread> threads;
std::atomic<bool> boolean{false};
for(int i = 0; i < 4; i++) {
threads.emplace_back([&]{thread_task(boolean);});
}
std::string line = "We reacted after a single thread finished!\n";
while(!boolean) std::this_thread::yield();
std::cout << line;
for(std::thread & thread : threads) {
thread.join();
}
return 0;
}
Example output I got on Ideone.com:
Thread slept for 1194ms.
We reacted after a single thread finished!
Thread slept for 1967ms.
Thread slept for 2390ms.
Thread slept for 2984ms.
This probably isn't the best code possible, because polling loops are not necessarily best practice, but it should work as a start.
There is no standard way of waiting on multiple threads.
You need to resort to operating system specific functions like WaitForMultipleObjects on Windows.
A Windows only example:
HANDLE handles[] = { t1.native_handle(), t2.native_handle(), };
auto res = WaitForMultipleObjects(2 , handles, FALSE, INFINITE);
Funnily , when std::when_any will be standardized, one can do a standard but wasteful solution:
std::vector<std::thread> waitingThreads;
std::vector<std::future<void>> futures;
for (auto& thread: threads){
std::promise<void> promise;
futures.emplace_back(promise.get_future());
waitingThreads.emplace_back([&thread, promise = std::move(promise)]{
thread.join();
promise.set_value();
});
}
auto oneFinished = std::when_any(futures.begin(), futures.end());
very wastefull, still not available , but standard.

mutex C++ good usage

I've some trouble with mutex, consider this exemple :
boost::mutex m;
void thread1_unstack(std::stack<std::string>& msg) {
while (true) {
if (msg.empty()) continue;
m.lock();
std::string msg_string = msg.top();
msg.pop();
std::cout << msg_string << std::endl;
m.unlock();
}
}
void thread2_stack(std::stack& msg) {
while (1) {
msg.push("very long message");
}
}
void wait_for_finish(std::stack& msg) {
while (!msg.empty()) sleep(1);
}
int main() {
std::stack<std::string> msg;
boost::thread t1 = boost::thread(boost::bind(&thread1_unstack, boost::ref(msg));
boost::thread t2 = boost::thread(boost::bind(&thread2_stack, boost::ref(msg));
wait_for_finish(msg);
t1.stop();
t2.stop();
}
So the probleme is with the function wait_for_finish. The function detect the stack is empty when msg.pop() is called, so thread are stopped juste after and sometimes, the message (std::cout) is not totally printed on the screen.
So I would like "lock" msg variable for thoses 3 lines :
std::string msg_string = msg.top();
msg.pop();
std::cout << msg_string << std::endl;
like that, wait_for_finish don't detect the stack is empty during std::cout.
I'm tryed to lock a boost::mutex and unlock it at the end, but nothing changed.
So I don't know how to solve it
you have to guard all access with a mutex:
boost::mutex m;
void thread1_unstack(std::stack<std::string>& msg) {
while (true) {
m.lock();
bool msgEmpty = msg.empty();
m.unlock();
if (msgEmpty) continue;
m.lock();
std::string msg_string = msg.top();
msg.pop();
std::cout << msg_string << std::endl;
m.unlock();
}
}
void thread2_stack(std::stack& msg) {
while (1) {
m.lock();
msg.push("very long message");
m.unlock();
}
}
void wait_for_finish(std::stack& msg) {
while(true) {
m.lock();
bool msgEmpty = msg.empty();
m.unlock();
if(msgEmpty) break;
sleep(1);
}
}
int main() {
std::stack<std::string> msg;
boost::thread t1 = boost::thread(boost::bind(&thread1_unstack, boost::ref(msg));
boost::thread t2 = boost::thread(boost::bind(&thread2_stack, boost::ref(msg));
wait_for_finish(msg);
t1.stop();
t2.stop();
}
Comments in our discussion reveal that you're using some kind of thread-safe waitable container. You need to stop the thread with its cooperation to make sure it has time to finish any work it's supposed to do on the last object. I would suggest this approach:
Have a stop flag that's either atomic or protected by a mutex. It should start out cleared.
When the thread gets an object from the container, before it prints it, it checks the stop flag. If the flag is set, the thread terminates.
When you want to stop the thread, set the stop flag, add a dummy object to the container, and then join the thread.
The dummy object unblocks the thread, and it won't get printed because the thread won't print with the stop flag set. By joining the thread, you ensure it's finished all the work it has to do before you terminate.
You can also use the "object of death" approach. For example, say it's not possible for your code to ever queue an empty string -- you could use an empty string as an "object of death". It works like this:
When you get an object from the container, check if it's the object of death. If it is, terminate.
To cause the thread to terminate, queue the object of death and then join the thread.
This has the same behavior. Queuing the object of death unblocks the thread (because the container is no longer empty and it only blocks if it is) and guarantees the thread will terminate when it's done (since the thread checks as soon as it unqueues it). Joining the thread ensures it has completely finished processing all objects prior to the object of death.