Edit: As it seems, the problem was me not actually creating a local instance of a lock_guard, but merely an anonymous temporary, which got destroyed again immediately, as pointed out by the comments below.
Edit2: Enabling clang's thread sanitizer helps to pinpoint these kinds of problems at run-time. It can be enabled via
clang++ -std=c++14 -stdlib=libc++ -fsanitize=thread *.cpp -pthread
This is probably in some way a duplicate question, but I couldn't find anything, so if it really is duplicate I'm sorry. This should be a beginner question anyway.
I was playing around with a simple "Counter" class, say inline in file
Counter.hpp:
#ifndef CLASS_COUNTER_HPP_
#define CLASS_COUNTER_HPP_
#include <mutex>
#include <string>
#include <exception>
class Counter
{
public:
explicit Counter(std::size_t v = 0) : value_{v} {}
std::size_t value() const noexcept { return value_; }
// void increment() { ++value_; } // not an atomic operation : ++value_ equals value_ = value_ + 1
// --> 3 operations: read, add, assign
void increment() noexcept
{
mutex_.lock();
++value_;
mutex_.unlock();
}
// void decrement() noexcept
// {
// mutex_.lock();
// --value_; // possible underflow
// mutex_.unlock();
// }
void decrement()
{
std::lock_guard<std::mutex>{mutex_};
if (value_ == 0)
{
std::string message{"New Value ("+std::to_string(value_-1)+") too low, must be at least 0"};
throw std::logic_error{message};
}
--value_;
}
private:
std::size_t value_;
std::mutex mutex_;
};
#endif
In main.cpp a Counter instance is supposed to be incremented and decremented
concurrently:
main.cpp:
#include <iostream>
#include <iomanip>
#include <array>
#include <thread>
#include <exception>
#include "Counter.hpp"
int
main ()
{
Counter counter{};
std::array<std::thread,4> threads;
auto operation = [&counter]()
{
for (std::size_t i = 0; i < 125; ++i)
counter.increment();
};
// std::for_each(begin(threads),end(threads),[&operation](auto& val) { val = std::thread{operation}; });
std::cout << "Incrementing Counter (" << std::setw(3) << counter.value() << ") concurrently...";
for (auto& t : threads)
{
t = std::thread{operation};
}
for (auto& t : threads)
t.join();
std::cout << " new value == " << counter.value() << '\n';
auto second_operation = [&counter]()
{
for (std::size_t i = 0; i < 125; ++i)
{
try
{
counter.decrement();
}
catch(const std::exception& e)
{
std::cerr << "\n***Exception while trying to decrement : " << e.what() << "***\n";
}
}
};
std::cout << "Decrementing Counter (" << std::setw(3) << counter.value() << ") concurrently...";
for (auto& t : threads)
t = std::thread{second_operation};
for (auto& t : threads)
t.join();
std::cout << " new value == " << counter.value() << '\n';
return 0;
The exception handling seems to work as it's supposed to, and the way I understand it std::lock_guard is supposed to guarantee unlocking a mutex once the lock_guard goes out of scope.
However it seems to be more complicated than that. While the incrementation correctly results in a final value of "500", the decrementation - which is supposed to result in "0" - doesn't work out. The result will be something between "0" and "16" or so.
If the timing is changed, for instance by using valgrind, it seems to work correctly every time.
I was able to pinpoint the problem to the use of std::lock_guard. If I define the decrement() function as this :
void decrement() noexcept
{
mutex_.lock();
--value_; // possible underflow
mutex_.unlock();
}
everything works out fine ( as long as there is no underflow).
But once I make a simple change to:
void decrement() noexcept
{
std::lock_guard<std::mutex>{mutex_};
--value_; // possible underflow
}
the behavior is like I described above. I presume I did not really understand the behavior and use cases of std::lock_guard. I would really appreciate it if you could point me into the right direction!
The program compiles via clang++ -std=c++14 -stdlib=libc++ *.cpp -pthread.
std::lock_guard<std::mutex>{mutex_}; Does not create a local. It creates a temporary which is destroyed at the end of the statement. This means your value is not protected by the lock. The lock guard must be a local:
void decrement() noexcept
{
std::lock_guard<std::mutex> guard {mutex_};
--value_; // possible underflow
}
The problem is that the line
std::lock_guard<std::mutex>{mutex_};
does not create a variable, but rather creates a temporary lock_guard object which gets destroyed again immediately. What you probably meant to write was:
std::lock_guard<std::mutex> guard{mutex_};
This creates a variable of type lock_guard, named guard, which gets destroyed when it leaves the scope (i.e. at the end of the function. Essentially, you forgot to name your variable.
Related
I am searching for a way to start multiple threads whose exact number can only be determined at runtime. The threads are not dependent on each other, so it's a fire-and-forget kind of problem.
The threads do need some context which is stored as internal variables of a class (Foo). Some of these variables are references. The class also holds a method that should be executed as the thread function (bar).
#include <iostream>
#include <string>
#include <vector>
#include <thread>
class Foo
{
public:
Foo(int a){
std::cout << "Created" << std::endl;
m_a = new int(a);
}
~Foo(){
std::cout << "Destroyed" << std::endl;
delete m_a;
}
void bar() {
std::cout << "Internal var: " << *m_a << std::endl;
}
private:
int* m_a;
};
int main() {
for(int i = 0; i < 5; i++) {
std::thread t(&Foo::bar, std::ref(Foo(i)));
// the threads will be joined at a later point, this is for demo purposes
}
return 0;
}
I get a compile error at this point:
error: use of deleted function ‘void std::ref(const _Tp&&) [with _Tp = Foo]’
I get it that this error is caused because of the temporary nature of the object created in the for-loop. But if I remove the std::ref function, I get a segfault: double free or corruption (fasttop)
I am sure that there must be a way of doing this, but I am unaware of that. I would expect some output like (probably in this order, but not guaranteed):
Created
Internal var: 0
Destroyed
Created
Internal var: 1
Destroyed
...
Thanks!
Problem 1: Foo is missing a copy/move constructor. See The rule of three/five/zero.
Add a copy constructor:
Foo(Foo const& that) : m_a(new int(*that.m_a)) {}
And/or a move constructor:
Foo(Foo && that) : m_a(that.m_a) { that.m_a = nullptr; }
Problem 2: Foo(i) is a temporary instance of Foo, it lives until the end of the full-expression (the ;).
std::thread t(&Foo::bar, std::ref(Foo(i)));
// ^
// Foo(i) is dead at this point while the thread is starting!
You want it to live longer than that, in order to be usable inside the thread.
For example, like this (also answers your question about creating threads in a loop):
int main() {
std::vector<Foo> inputs;
std::vector<std::thread> threads;
for(int i = 0; i < 5; i++) {
inputs.emplace_back(i);
threads.emplace_back(&Foo::bar, &inputs.back());
}
for (auto& t : threads) {
t.join();
}
}
Note: std::ref(Foo(i)) doesn't compile because it has protection against returning references to temporaries (precisely to prevent issues like these).
Here is a minimaly fixed version of your code:
it includes the move ctor for Foo class (and explicitely deletes copy ctor)
it moves the threads into a vector
it joins the threads
Code:
#include <string>
#include <vector>
#include <thread>
#include <iostream>
class Foo
{
public:
Foo(int a) {
std::cout << "Created" << std::endl;
m_a = new int(a);
}
~Foo() {
if (m_a != NULL) {
std::cout << "Destroyed" << std::endl;
delete m_a;
}
}
Foo(const Foo& other) = delete; //not used here
Foo(Foo&& other) {
std::cout << "Move ctor" << '\n';
m_a = other.m_a;
other.m_a = nullptr;
}
void bar() {
std::cout << "Internal var: " << *m_a << std::endl;
}
private:
int* m_a;
};
int main() {
std::vector<std::thread> vec;
for (int i = 0; i < 5; i++) {
std::thread t(&Foo::bar, Foo(i));
vec.push_back(std::move(t));
}
for (auto& t : vec) {
t.join();
}
return 0;
}
The chief design failure seems that t is a variable inside the loop. That means it's destroyed at the end of each iteration - you never have 5 std::thread instances at the same time. Also, you fail to call join on those threads.
The std::ref apparently hides this problem and replaces it with another problem, but your original thread creation was correct: std::thread t(&Foo::bar, Foo(i)).
You probably want a std::list<std::thread>, and use std::list::emplace_back to create a variable amount. std::list<std::thread> allows you to remove threads in any order from the list.
I have this simple class:
struct Foo {
void Run() {
this->bgLoader = std::thread([this]() mutable {
//do something
this->onFinish_Thread();
});
}
std::function<void()> onFinish_Thread;
std::thread bgLoader;
};
That is called from C-API:
void CApiRunFoo(){
Foo foo;
foo.onFinish_Thread = []() {
//do something at thread end
};
foo.Run();
}
I want to run CApiRunFoo, return from it but keep the thread running until it is finished.
Now, the problem is, that once CApiRunFoo end, foo goes out of scope even if background thread is still running. If I change foo to object via new, it will run, but it will cause memory leak.
I was thinking to create destructor with:
~Foo(){
if (bgLoader.joinable()){
bgLoader.join();
}
}
but I am not sure if it can cause deadlock or not plus it probably wont cause CApiRunFoo to return until the thread finishes.
Is there any solution/design pattern to this problem?
You could return the Foo instance to the C program:
struct Foo {
~Foo() {
if (bgLoader.joinable()) {
run = false;
bgLoader.join();
}
}
void Run() {
run = true;
this->bgLoader = std::thread([this]() mutable {
while(run) {
// do stuff
}
this->onFinish_Thread();
});
}
std::atomic<bool> run;
std::function<void()> onFinish_Thread;
std::thread bgLoader;
};
The C interface:
extern "C" {
struct foo_t {
void* instance;
};
foo_t CApiRunFoo() {
Foo* ptr = new Foo;
ptr->onFinish_Thread = []() {
std::cout << "done\n";
};
ptr->Run();
return foo_t{ptr};
}
void CApiDestroyFoo(foo_t x) {
auto ptr = static_cast<Foo*>(x.instance);
delete ptr;
}
}
And a C program:
int main() {
foo_t x = CApiRunFoo();
CApiDestroyFoo(x);
}
Demo
As it seems you'd like the Foo objects to automatically self destruct when the thread finishes, you could run them detached and let them delete this; when done.
#include <atomic>
#include <condition_variable>
#include <cstdint>
#include <iostream>
#include <functional>
#include <mutex>
#include <thread>
// Counting detached threads and making sure they are all finished before
// exiting the destructor. Used as a `static` member of `Foo`.
struct InstanceCounter {
~InstanceCounter() {
run = false;
std::unique_lock lock(mtx);
std::cout << "waiting for " << counter << std::endl;
while(counter) cv.wait(lock);
std::cout << "all done" << std::endl;
}
void operator++() {
std::lock_guard lock(mtx);
std::cout << "inc: " << ++counter << std::endl;
}
void operator--() {
std::lock_guard lock(mtx);
std::cout << "dec: " << --counter << std::endl;
cv.notify_one(); // if the destructor is waiting
}
std::atomic<bool> run{true};
std::mutex mtx;
std::condition_variable cv;
unsigned counter = 0;
};
struct Foo {
bool Run() {
try {
++ic; // increase number of threads in static counter
bgLoader = std::thread([this]() mutable {
while(ic.run) {
// do stuff
}
// if onFinish_Thread may throw - you may want to try-catch:
onFinish_Thread();
--ic; // decrease number of threads in static counter
delete this; // self destruct
});
bgLoader.detach();
return true; // thread started successfully
}
catch(const std::system_error& ex) {
// may actually happen if the system runs out of resources
--ic;
std::cout << ex.what() << ": ";
delete this;
return false; // thread not started
}
}
std::function<void()> onFinish_Thread;
private:
~Foo() { // private: Only allowed to self destruct
std::cout << "deleting myself" << std::endl;
}
std::thread bgLoader;
static InstanceCounter ic;
};
InstanceCounter Foo::ic{};
Now the C interface becomes more like what you had in the question.
#include <stdbool.h>
extern "C" {
bool CApiRunFoo() {
Foo* ptr = new Foo;
ptr->onFinish_Thread = []() {
std::cout << "done" << std::endl;
};
return ptr->Run();
// it looks like `ptr` is leaked here, but it self destructs later
}
}
Demo
Your program should call join and finish the new thread at some point in future (see also this question with answer). To do that, it should hold a reference (in a wide sense) to the thread object. In your current design, your foo is such a reference. So you are not allowed to lose it.
You should think about a place where it makes sense to do join in your code. This same place should hold your foo. If you do that, there is no problem, because foo contains also the onFinish_Thread object.
sorry but I cant understand why 2 times destructor called?
#include <iostream>
#include <thread>
class myClass
{
public:
int integer;
void operator()()
{
std::cout << "class: " << integer << "\t" << std::this_thread::get_id() << std::endl;
}
myClass(int h)
: integer{h}
{
}
~myClass()
{
std::cout << "MyClass by int: " << integer << " destroyed!" << std::endl;
}
};
bool myFunc(int x)
{
myClass tempClass(x);
std::thread one(tempClass);
one.join();
if (x <= 0)
return 0;
else
return myFunc(x - 1);
}
int main()
{
myFunc(10);
return 0;
}
note : I'm just trying in MultiThreads. (training)
and one more problem is that why before joining thread , my class has destroyed!
In the line
std::thread one(tempClass);
a copy of tempClass is created. Later on, both instances of myClass are destroyed.
You can pass tempClass by reference by using std::ref, but then you have to guarantee that tempClass remains valid (e.g. does not go out of scope, is brought in an invalid state by the main thread) throughout the life time of your thread (one).
You can also move tempClass into the other thread. You would still end up with two destructor calls and it would hardly make any difference in your case, but if myClass is difficult to copy, it can make a difference. In that case, you may want to read up on move semantics.
The idea is to have instance for each thread, so I created new instance for every new thread::id like that :
struct doSomething{
void test(int toto) {}
};
void test(int toto)
{
static std::map<std::thread::id, doSomething *> maps;
std::map<std::thread::id, doSomething *>::iterator it = maps.find(std::this_thread::get_id());
if (it == maps.end())
{
// mutex.lock() ?
maps[std::this_thread::get_id()] = new doSomething();
it = maps.find(std::this_thread::get_id());
// mutex.unlock() ?
}
it->second->test(toto);
}
Is it a good idea?
Having a mutex lock after you've accessed the map would not be enough. You can't go anywhere near the map without a mutex because another thread might take the mutex to modify the map while you are reading from it.
{
std::unique_lock<std::mutex> lock(my_mutex);
std::map<std::thread::id, doSomething *>::iterator it = maps.find(std::this_thread::get_id());
if (it != maps.end())
return *it;
auto ptr = std::make_unique<doSomething>();
maps[std::this_thread::get_id()] = ptr.get();
return ptr.release();
}
But unless you have some special/unique use case, this is an already-solved problem through thread-local storage, and since you have C++11 you have the thread_local storage specifier.
Note that I'm using a mutex here because cout is a shared resource and yield just to encourage a little more interleaving of the workflow.
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
static std::mutex cout_mutex;
struct CoutGuard : public std::unique_lock<std::mutex> {
CoutGuard() : unique_lock(cout_mutex) {}
};
struct doSomething {
void fn() {
CoutGuard guard;
std::cout << std::this_thread::get_id() << " running doSomething "
<< (void*)this << "\n";
}
};
thread_local std::unique_ptr<doSomething> tls_dsptr; // DoSomethingPoinTeR
void testFn() {
doSomething* dsp = tls_dsptr.get();
if (dsp == nullptr) {
tls_dsptr = std::make_unique<doSomething>();
dsp = tls_dsptr.get();
CoutGuard guard;
std::cout << std::this_thread::get_id() << " allocated "
<< (void*)dsp << "\n";
} else {
CoutGuard guard;
std::cout << std::this_thread::get_id() << " re-use\n";
}
dsp->fn();
std::this_thread::yield();
}
void thread_fn() {
testFn();
testFn();
testFn();
}
int main() {
std::thread t1(thread_fn);
std::thread t2(thread_fn);
t2.join();
t1.join();
}
Live demo: http://coliru.stacked-crooked.com/a/3dec7efcb0018549
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
140551597459200 allocated 0x7fd4a80008e0
140551597459200 running doSomething 0x7fd4a80008e0
140551605851904 allocated 0x7fd4b00008e0
140551605851904 running doSomething 0x7fd4b00008e0
140551605851904 re-use
140551605851904 running doSomething 0x7fd4b00008e0
140551597459200 re-use
140551605851904 re-use
140551597459200 running doSomething 0x7fd4a80008e0
140551605851904 running doSomething 0x7fd4b00008e0
140551597459200 re-use
140551597459200 running doSomething 0x7fd4a80008e0
It's a little hard to spot but thread '9200 allocated ..4a80.. whereas thread '1904 allocated ..4b00..
No, not a good idea.
std::map's methods themselves are not thread safe.
In order to really make it a "good idea", you must also make all access to your std::map thread-safe, by using a mutex, or an equivalent.
This includes not just the parts you have commented out, but also all other methods you're using, like find().
Everything that touches your std::map must be mutex-protected.
Consider that in some library somewhere (which we have no access to change), we have a Counter class:
class Counter {
int count;
public:
Counter() : count(0) { }
void bump() { ++count; }
int getCount() const { return count; }
};
which, by its very nature, is mutable. If it's const, it's pretty worthless.
And in our code, we "use" that Counter. Badly.
#include <string>
#include <iostream>
#include <Counter.hpp>
using std::cout;
using std::endl;
void breakTheHellOutOfCounter(Counter &c) {
// This is OK
c.bump();
// Oh noes!
c = Counter();
}
int main() {
Counter c;
c.bump(); c.bump(); c.bump();
std::cout << "Count was " << c.getCount() << std::endl;
breakTheHellOutOfCounter(c);
std::cout << "Count is now " << c.getCount() << std::endl;
}
Note that breakTheHellOutOfCounter overwrites main's counter with a shiny new one, resetting the count. That's going to cause the caller some grief. (Imagine something a lot more harmful happening, and you'll see where I'm going here.)
I need to be able to bump c (and thus, I need it mutable), but I want breakTheHellOutOfCounter() to fail miserably due to trying to replace c. Is there a way I can change things (other than the Counter class) to make that happen?
(I'm aware that at the lowest levels, this is all but impossible to enforce. What I want is a way to make it hard to do accidentally.)
The cleanest solution I can see to this without modifying counter itself is something like:
#include <string>
#include <iostream>
#include <Counter.hpp>
template <typename T>
struct Unbreakable : public T {
Unbreakable<T>& operator=(const Unbreakable<T>&) = delete;
Unbreakable<T>& operator=(Unbreakable<T>&&) = delete;
template <typename ...Args>
Unbreakable(Args&& ...args) : T(std::forward<Args>(args)...) {}
};
using std::cout;
using std::endl;
void breakTheHellOutOfCounter(Unbreakable<Counter> &c) {
// this is ok
c.bump();
// oh noes!
c = Counter();
}
int main() {
Unbreakable<Counter> c;
c.bump(); c.bump(); c.bump();
std::cout << "Count was " << c.getCount() << std::endl;
breakTheHellOutOfCounter(c);
std::cout << "Count is now " << c.getCount() << std::endl;
}
Which correctly gives an error from your "oh noes" line. (Example uses C++11, but C++98 solution is similar)
That doesn't rule out usage like:
Counter& br = c;
br = Counter();
of course, but without modifying Counter itself I don't think that's avoidable.
The simplest way to do this is to remove the assignment operator from the Counter class. However, since you don't have the ability to change the Counter class, your only real option is to wrap the Counter class in a class with no assignment operator and use that instead.
As Michael Anderson said, you can wrap your counter object in a class that prevents assignment.
class CounterProxy {
Counter& counter;
CounterProxy & operator=(const CounterProxy&);
public:
CounterProxy(Counter& c) : counter(c) {}
void bump() { counter.bump(); }
int getCount() const { return counter.getCount(); }
};
void breakTheHellOutOfCounter(CounterProxy &c) {
// this is ok
c.bump();
// not oh noes!
c = CounterProxy(Counter());
}
int main() {
Counter c;
c.bump(); c.bump(); c.bump();
std::cout << "Count was " << c.getCount() << std::endl;
breakTheHellOutOfCounter(CounterProxy(c));
std::cout << "Count is now " << c.getCount() << std::endl;
}
You can use this method whenever you want to limit the operations that can be performed on an object.
EDIT: You're probably already aware of this and looking for a more elegant solution, but the code might help others.
By allowing bump via a mutable reference, you are giving the function access to mess with the object state. There is nothing special about assignment; it's just a function that mutates the object in some way. It could just as well be a function called CopyStateFromAnotherInstance() instead of operator =().
So the real problem is: How do you allow only certain functions but hide others? By using an interface:
class IBumpable
{
void bump() ...
};
class Counter : IBumpable
{
....
};
void functionThatCannotBreakCounter(IBumpable& counter) { ... }