Calling a function which is inside a Thread - c++

I was doing Unit Testing and finding code coverage using gtest and lcov.
My function is
void MyClass::MyFunction(const std::string& argument1, const std::string& argument2) {
std::thread([this, argument1, argument2]() {
std::unique_lock<std::mutex> live_lock_(live_mutex_);
int64_t time_stamp = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
int64_t time_to_live = myList[argument1] - (time_stamp % myList[argument1]);
cond_var_.wait_for(time_to_live_lock_, std::chrono::milliseconds(time_to_live), [this, argument1] { return cond_var_status_[argument1]; });
if (message_master_.find(argument1) != message_master_.end()) {
//something
}
}).detach();
std::cout<< "end line is executed"<<std::endl; }
and my test function is
TEST(test, test1) {
Myclass testObj;
testObj.MyFunction("arg1", "arg2");
ASSERT_EQ("","");
};
When I run the test, all codes except those inside thread are executed.
So is there any solution to call those codes inside thread too?

How do you know none of those lines are being executed?
I would suggest making a test program, compiling with -g and -Wall, then using gdb to make sure a thread is actually being created. If it is, step through the code.
It could be that the compiler gets rid of code it thinks is doing nothing.

This is how I would test it (I modified the code a little, but in principle it is the same thing. All the globals shall be moved to MyClass most probably):
#include <atomic>
#include <condition_variable>
#include <map>
#include <mutex>
#include <thread>
std::mutex time_to_live_mutex_;
std::map<std::string, int64_t> myList;
std::map<std::string, bool> cond_var_status_;
std::map<std::string, std::string> incoming_message_master_;
std::condition_variable cond_var_;
std::atomic_bool something_happened{false};
void foo(const std::string& argument1, const std::string& argument2) {
std::thread([argument1, argument2]() {
std::unique_lock<std::mutex> time_to_live_lock_(time_to_live_mutex_);
int64_t time_stamp = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
int64_t time_to_live = myList[argument1] - (time_stamp % myList[argument1]);
cond_var_.wait_for(time_to_live_lock_, std::chrono::milliseconds(time_to_live), [argument1] { return cond_var_status_[argument1]; });
if (incoming_message_master_.find(argument1) != incoming_message_master_.end()) {
//something
something_happened = true;
}
}).detach();
}
TEST(TestFoo, testing_foo_thread) {
int64_t timeout = 10000;
myList["bar"] = timeout; // so that cond variable waits long time
cond_var_status_["bar"] = false; // so that cond variable returns false at first try
incoming_message_master_["bar"] = std::string("42"); // so that something can happen
foo("bar", "fiz");
ASSERT_FALSE(something_happened); // cond variable is still waiting at this point
{
std::unique_lock<std::mutex> time_to_live_lock_(time_to_live_mutex_);
cond_var_status_["bar"] = true; // so that cond variable returns eventually
}
while(!something_happened && timeout > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
timeout -= 10;
}
ASSERT_TRUE(something_happened); // cond variable is not waiting, should have returned
}

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;
}

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.

What is wrong with std::lock_guard

I have simple code: first thread pushes std::strings to the std::list, and second thread pops std::strings from this std::list. All std::lists operations are protected with std::mutex m. This code permanently prints error to console: "Error: lst.begin() == lst.end()".
If I replace std::lock_guard with construction m.lock() and m.unlock() the code begins work correctly. What is wrong with std::lock_guard?
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <string>
std::mutex m;
std::list<std::string> lst;
void f2()
{
for (int i = 0; i < 5000; ++i)
{
std::lock_guard<std::mutex> { m };
lst.push_back(std::to_string(i));
}
m.lock();
lst.push_back("-1"); // last list's element
m.unlock();
}
void f1()
{
std::string str;
while (true)
{
m.lock();
if (!lst.empty())
{
if (lst.begin() == lst.end())
{
std::cerr << "Error: lst.begin() == lst.end()" << std::endl;
}
str = lst.front();
lst.pop_front();
m.unlock();
if (str == "-1")
{
break;
}
}
else
{
m.unlock();
std::this_thread::yield();
}
}
}
// tested in MSVS2017
int main()
{
std::thread tf2{ f2 };
f1();
tf2.join();
}
You did not obey CppCoreGuidelines CP.44: Remember to name your lock_guards and unique_locks :).
In
for (int i = 0; i < 5000; ++i)
{
std::lock_guard<std::mutex> { m };
lst.push_back(std::to_string(i));
}
you are only creating a temporary std::lock_guard object which is created and destroyed immediately. You need to name the object like in
{
std::lock_guard<std::mutex> lg{ m };
lst.push_back(std::to_string(i));
}
so that the lock guard lives until the end of the block.
And as you already recognized (CppCoreGuidelines):
Use RAII lock guards (lock_guard, unique_lock, shared_lock), never call mutex.lock and mutex.unlock directly (RAII)
If you are using Microsoft Visual Studio, I recommend using the code analysis and activating at least the Microsoft Native Recommended Rules. If you do this you will get a compiler analysis warning.
warning C26441: Guard objects must be named (cp.44).

Processing an array of objects with multithreading - invalid use of void expression error

I need to run some number of threads to process an array of objects.
So I've written this piece of code :
unsigned int object_counter = 0;
while(object_counter != (obj_max - left))
{
thread genThread[thread_num];//create thread objects
///launch threads
int thread_index = 0;
for (; thread_index<thread_num; thread_index++)
{
genThread[thread_index] = thread(object[object_counter].gen_maps());//launch a thread
object_counter++;
if(object_counter == (obj_max - left)
{
break;
}
}
///finish threads
for (; thread_index>0; thread_index--)
{
genThread[thread_index].join();
}
}
Basically, there is an array of objects (number of objects = obj_max - left).
Each object has a function (void type function) called gen_maps() that generates a terrain.
What I want to do is running all gen_maps() functions from all objects using multithreading.
A maximum number of threads is stored in thread_num variable.
But when I'm trying to compile this code I'm getting an error:
error: invalid use of void expression
genThread[thread_index] = thread(object[object_counter].gen_maps(), thread_index);//launch a thread
^
How can I fix this issue?
A more extendable way to manage an arbitrarily large number of jobs with a smaller number of threads is to use a thread pool.
Here's a naive implementation (for better efficiency there would be 2 condition variables to manage control and state reporting) which allows the initiator to add an arbitrary number of jobs or threads and wait for all jobs to be complete.
#include <thread>
#include <condition_variable>
#include <mutex>
#include <vector>
#include <functional>
#include <deque>
#include <cassert>
#include <ciso646>
#include <iostream>
struct work_pool
{
std::mutex control_mutex;
std::condition_variable control_cv;
std::deque<std::function<void()>> jobs;
bool terminating = false;
std::size_t running = 0;
std::vector<std::thread> threads;
work_pool(std::size_t n = std::thread::hardware_concurrency())
{
add_threads(n);
}
work_pool(const work_pool&) = delete;
work_pool& operator=(const work_pool&) = delete;
~work_pool()
{
wait();
shutdown();
}
void add_threads(std::size_t n)
{
while (n--)
{
threads.emplace_back([this]{
run_jobs();
});
}
}
void run_jobs()
{
while (1)
{
auto lock = std::unique_lock(control_mutex);
control_cv.wait(lock, [this] {
return terminating or not jobs.empty();
});
if (terminating) return;
++running;
auto job = std::move(jobs.front());
jobs.pop_front();
lock.unlock();
job();
lock.lock();
--running;
lock.unlock();
control_cv.notify_one();
}
}
void shutdown()
{
auto lock = std::unique_lock(control_mutex);
terminating = true;
lock.unlock();
control_cv.notify_all();
for (auto&& t : threads) {
if (t.joinable()) {
t.join();
}
}
threads.clear();
}
void wait()
{
auto lock = std::unique_lock(control_mutex);
control_cv.wait(lock, [this] {
return jobs.empty() and not running;
});
}
template<class F>
void add_work(F&& f)
{
auto lock = std::unique_lock(control_mutex);
assert(not terminating);
jobs.emplace_back(std::forward<F>(f));
lock.unlock();
control_cv.notify_all();
}
};
// dummy function for exposition
void generate_map() {}
int main()
{
work_pool pool;
for(int i = 0 ; i < 100000 ; ++i)
pool.add_work(generate_map);
pool.wait();
// maps are now all generated
std::cout << "done" << std::endl;
}
With object[object_counter].gen_maps() you call the function gen_maps and use the returned value as the thread function. Apparently gen_maps is declared to return void which leads to the error you get.
You need to pass a pointer to the function, and then pass the object it should be called on as an argument to the thread:
thread(&SomeClass::gen_maps, object[object_counter])

Using a C++11 condition variable in VS2012

I can't get code working reliably in a simple VS2012 console application consisting of a producer and consumer that uses a C++11 condition variable. I am aiming at producing a small reliable program (to use as the basis for a more complex program) that uses the 3 argument wait_for method or perhaps the wait_until method from code I have gathered at these websites:
condition_variable:
wait_for,
wait_until
I'd like to use the 3 argument wait_for with a predicate like below except it will need to use a class member variable to be most useful to me later. I am receiving "Access violation writing location 0x__" or "An invalid parameter was passed to a service or function" as errors after only about a minute of running.
Would steady_clock and the 2 argument wait_until be sufficient to replace the 3 argument wait_for? I've also tried this without success.
Can someone show how to get the code below to run indefinitely with no bugs or weird behavior with either changes in wall-clock time from daylight savings time or Internet time synchronizations?
A link to reliable sample code could be just as helpful.
// ConditionVariable.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
#include <atomic>
#define TEST1
std::atomic<int>
//int
qcount = 0; //= ATOMIC_VAR_INIT(0);
int _tmain(int argc, _TCHAR* argv[])
{
std::queue<int> produced_nums;
std::mutex m;
std::condition_variable cond_var;
bool notified = false;
unsigned int count = 0;
std::thread producer([&]() {
int i = 0;
while (1) {
std::this_thread::sleep_for(std::chrono::microseconds(1500));
std::unique_lock<std::mutex> lock(m);
produced_nums.push(i);
notified = true;
qcount = produced_nums.size();
cond_var.notify_one();
i++;
}
cond_var.notify_one();
});
std::thread consumer([&]() {
std::unique_lock<std::mutex> lock(m);
while (1) {
#ifdef TEST1
// Version 1
if (cond_var.wait_for(
lock,
std::chrono::microseconds(1000),
[&]()->bool { return qcount != 0; }))
{
if ((count++ % 1000) == 0)
std::cout << "consuming " << produced_nums.front () << '\n';
produced_nums.pop();
qcount = produced_nums.size();
notified = false;
}
#else
// Version 2
std::chrono::steady_clock::time_point timeout1 =
std::chrono::steady_clock::now() +
//std::chrono::system_clock::now() +
std::chrono::milliseconds(1);
while (qcount == 0)//(!notified)
{
if (cond_var.wait_until(lock, timeout1) == std::cv_status::timeout)
break;
}
if (qcount > 0)
{
if ((count++ % 1000) == 0)
std::cout << "consuming " << produced_nums.front() << '\n';
produced_nums.pop();
qcount = produced_nums.size();
notified = false;
}
#endif
}
});
while (1);
return 0;
}
Visual Studio Desktop Express had 1 important update which it installed and Windows Update has no other important updates. I'm using Windows 7 32-bit.
Sadly, this is actually a bug in VS2012's implementation of condition_variable, and the fix will not be patched in. You'll have to upgrade to VS2013 when it's released.
See:
http://connect.microsoft.com/VisualStudio/feedback/details/762560
First of all, while using condition_variables I personally prefer some wrapper classes like AutoResetEvent from C#:
struct AutoResetEvent
{
typedef std::unique_lock<std::mutex> Lock;
AutoResetEvent(bool state = false) :
state(state)
{ }
void Set()
{
auto lock = AcquireLock();
state = true;
variable.notify_one();
}
void Reset()
{
auto lock = AcquireLock();
state = false;
}
void Wait(Lock& lock)
{
variable.wait(lock, [this] () { return this->state; });
state = false;
}
void Wait()
{
auto lock = AcquireLock();
Wait(lock);
}
Lock AcquireLock()
{
return Lock(mutex);
}
private:
bool state;
std::condition_variable variable;
std::mutex mutex;
};
This may not be the same behavior as C# type or may not be as efficient as it should be but it gets things done for me.
Second, when I need to implement a producing/consuming idiom I try to use a concurrent queue implementation (eg. tbb queue) or write a one for myself. But you should also consider making things right by using Active Object Pattern. But for simple solution we can use this:
template<typename T>
struct ProductionQueue
{
ProductionQueue()
{ }
void Enqueue(const T& value)
{
{
auto lock = event.AcquireLock();
q.push(value);
}
event.Set();
}
std::size_t GetCount()
{
auto lock = event.AcquireLock();
return q.size();
}
T Dequeue()
{
auto lock = event.AcquireLock();
event.Wait(lock);
T value = q.front();
q.pop();
return value;
}
private:
AutoResetEvent event;
std::queue<T> q;
};
This class has some exception safety issues and misses const-ness on the methods but like I said, for a simple solution this should fit.
So as a result your modified code looks like this:
int main(int argc, char* argv[])
{
ProductionQueue<int> produced_nums;
unsigned int count = 0;
std::thread producer([&]() {
int i = 0;
while (1) {
std::this_thread::sleep_for(std::chrono::microseconds(1500));
produced_nums.Enqueue(i);
qcount = produced_nums.GetCount();
i++;
}
});
std::thread consumer([&]() {
while (1) {
int item = produced_nums.Dequeue();
{
if ((count++ % 1000) == 0)
std::cout << "consuming " << item << '\n';
qcount = produced_nums.GetCount();
}
}
});
producer.join();
consumer.join();
return 0;
}