mutable thread vs non-const method - c++

I have a class where I want to call a method in a thread.
My methods don't modify the class attributs so I expect them to be const, but they instantiate a thread, so they can't.
What is the best choice between putting the std::thread mutable, remove the const because of the thread, edit : or using detached threads ?
class ValidationSound
{
public:
[... CTOR DTOR ...]
void emitSuccessSoundAsync() const
{
if(m_thread.joinable())
{
m_thread.join();
}
m_thread = std::thread(&ValidationSound::emitSound, this, std::cref(m_bipsParameters.first));
};
void emitFailureSoundAsync() const
{
if(m_thread.joinable())
{
m_thread.join();
}
m_thread = std::thread(&ValidationSound::emitSound, this, std::cref(m_bipsParameters.second));
};
void emitSound(const BipParameters& bipParam) const
{
//BIP BIP THE BUZZER
};
private:
std::pair<BipParameters, BipParameters> m_bipsParameters;
mutable std::thread m_thread;
};

My methods don't modify the class attributs so I expect them to be const, but they instantiate a thread, so they can't.
But your methods do modify class attributes. Your std::thread is a class attribute and once any of your methods are called, that attribute will change (begin running) and continue to change state even after the methods have exited.
What is the best choice between putting the std::thread mutable, remove the const because of the thread, edit : or using detached threads ?
In this case, I'd recommend removing the const from method signatures. Const just confuses the interface and could fool users into thinking it's thread-safe. If the methods were mutex protected and blocked for the duration of the thread execution time, you could make a stronger argument for mutable and const, but given your current implementation I wouldn't.
Edit: Said another way, imagine you've gone ahead and created a single const instance of you ValidationSound class. It would be very easy for a user of this class to call your instance in a way that creates many threads all playing different sounds interleaved at different times. Is that how you'd envision a const instance of this class behaving? It's certainly not how I'd envision it looking purely at the interface.

Related

Design of a holder class that will be used to store data at multiple places in the program

I am trying to design a class that works as a data holder (contains lot of members, getters and setters). This class shall be used at multiple other threads in the program and can be used for data exchange, i.e. one component updates the object and others can read out the changed values when needed.
Even if write of a member (by calling setter) can happen only at once place, however getter can be called at multiple places.
Below is the class code.
#include <mutex>
class DataType{};
class DataStore
{
private:
mutable std::mutex _mtx;
DataType _member;
// different other member!
public:
DataStore(): _member(){}
~DataStore(){}
// setters can be called from many places!
void setMember(const DataType& val)
{
std::lock_guard<std::mutex> lock(_mtx);
_member = val;
}
// getters can be called from many places!
const DataType& getMember() const
{
std::lock_guard<std::mutex> lock(_mtx);
return member;
}
};
Questions:
What is best way to create and share instance of this class, singleton or const DataStore& or shared_ptr<DataStore>?
Do we need to make it thread-safe even if calling setMember happens only at once place? What are the possibilities to make it thread-safe? Will the existing code work?
Some of the setters can be called very frequently, do I need to make the member as reference, DataType& _member;?
What is best way to create and share instance of this class, singleton or const DataStore& or shared_ptr<DataStore>?
Access to the class object is always read operation when you choose singleton or shard_ptr.(I cannot understand what const DataStore& means.)
Do we need to make it thread-safe even if calling setMember happens only at once place? What are the possibilities to make it thread-safe? Will the existing code work?
getMember returns const lvalue reference. So that your code doesn't lock anything. copy object or lock data access outside of this class.
You need to ensure that read operation and write operation doesn't occur at same time.
Some of the setters can be called very frequently, do I need to make the member as reference, DataType& _member;?
As already pointed out, you should use std::shared_mutex outside of the class to avoid object copy. this means that you can simply remove the DataStore class because they are no longer needed.

Avoiding deadlock in case of nested calls when designing thread safe class

I understand I can use a mutex member in a class and lock it inside each method to prevent data race in multithreading environment. However, such method might incur deadlock if there are nested calls in the class's methods, like the add_one() and add_two() in below class. Using different mutex for each method is a workaround. But are there more principled and elegant way to prevent deadlock in the case of nested calls?
class AddClass {
public:
AddClass& operator=(AddClass const&) = delete; // disable copy-assignment constructor
AddClass(int val) : base(val) {}
int add_one() { return ++base; }
int add_two() {
add_one;
add_one;
return base;
}
private:
int base;
};
There is std::recursive_mutex exactly for this purpose.
Another approach that avoids overhead incurred by recursive mutex is to separate public synchronized interface from private non-synchronized implementation:
class AddClass {
public:
AddClass& operator=(AddClass const&) = delete; // disable copy-assignment constructor
AddClass(int val) : base(val) {}
int add_one() {
std::lock_guard<std::mutex> guard{mutex};
return add_one_impl();
}
int add_two() {
std::lock_guard<std::mutex> guard{mutex};
return add_two_impl();
}
private:
int base;
std::mutex mutex;
int add_one_impl() {
return ++base;
}
int add_two_impl() {
add_one_impl();
add_one_impl();
return base;
}
};
Note, however, that this is not always possible. For example if you have a method that accepts a callback and calls it while holding the lock, the callback might try to call some other public method of your class, and you are again faced with the double locking attempt.
A recursive mutex is a lockable object, just like mutex, but allows the same thread to acquire multiple levels of ownership over the mutex object.
When and how to Use Recursive Mutex-- Link Below
Recursive Mutex
Note: Recursive and non-recursive mutexes have different use cases.
Hope it helps.
The general solution for this is called a reentrant mutex
While any attempt to perform the "lock" operation on an ordinary mutex
(lock) would either fail or block when the mutex is already locked, on
a recursive mutex this operation will succeed if and only if the
locking thread is the one that already holds the lock. Typically, a
recursive mutex tracks the number of times it has been locked, and
requires equally many unlock operations to be performed before other
threads may lock it.
There's one in the C++11 standard library: http://en.cppreference.com/w/cpp/thread/recursive_mutex
Implement the public interface with functions that lock your locks and call private member functions that do the work. The private functions can call each other without the overhead of re-locking mutexes and without resorting to recursive mutexes, which are regarded by many as a sign of design failure.

C++ - Passing signals between threads of to functions of different classes?

Basic problem, but haven't been able to find solution. I need .notify_one() to be picked up by DERIVED_TWO, I've tested the code within the same class and it works fine?
#include <mutex>
class BASE
{
public:
std::mutex(mu);
std::condition_variable condition;
};
class DERIVED_ONE:public BASE
{
public:
auto DoStuff()->void
{
std::unique_lock<mutex> lock(mu);
//Do Stuff here...
lock.unlock();
condition.notify_one();
}
};
class DERIVED_TWO:public BASE
{
public:
auto DoMoreStuff()->void
{
std::unique_lock<mutex> lock(mu);
condition.wait(lock);
//Do even more stuff...
lock.unlock();
}
};
SIDE NOTE:
I could use a polymorphic object to pass messages between classes, although this seems a messy solution
Different instances of your classes will not share the same condition variable object unless you declare it static. And I also doubt that you would want them to.
I would implement a separate message queue class that could be instantiated as communication channels as needed and passed to the instances of your other classes at creation time.

Avoid deadlock in a single thread

I have the following problem: I have a class that needs to be protected from simultaneous access from different threads. The class has two methods: lock() and unlock() using (g_mutex_lock / g_mutex_unlock with a per-object GMutex). Now a locking method looks like this:
void Object::method()
{
lock();
// do stuff modifying the object
unlock();
}
Now lets assume that I have two mwthods of this type, method1() and method2() which I call one after another:
object.method1();
// but what if some other thread modifies object in between
object.method2();
I tried locking the object before this block und unlocking it again, but in this case
there is a deadlock even with a single thread because the GMutex doesn't know that it has already been locked by the same thread. A solution would be to modify the method to accept an additional bool to determine whether the object is already locked. But is there a more elegant concept? Or is this a shortcoming regarding the design concept in total?
The recursive mutex solution mentioned in other responses and comments will work just fine, but in my experience it leads to code that is harder to maintain, because once you switch to a recursive mutex it is all too easy to abuse it and lock all over the place.
Instead, I prefer to reorganize the code so that locking once is sufficient. In your example I would define the class as follows:
class Object {
public:
void method1() {
GMutexLock scopeLock(&lock);
method1_locked();
}
void method2() {
GMutexLock scopeLock(&lock);
method2_locked();
}
void method1_and_2() {
GMutexLock scopeLock(&lock);
method1_locked();
method2_locked();
}
private:
void method1_locked();
void method2_locked();
GMutex lock;
};
The "locked" versions of your methods are private, so they are only accessible from inside the class. The class takes responsibility in never calling these without the lock taken.
From the outside you have three choices of methods to call, depending on which of the methods you want to run.
Note that another improvement I've made is to not use explicit locking primitives but instead use the scope indirectly to lock and unlock. This is what GMutexLock does. An example implementation for this class is below:
class GMutexLock {
private:
GMutex* m;
GMutexLock(const GMutexLock &mlock); // not allowed
GMutexLock &operator=(const GMutexLock &); // not allowed
public:
GMutexLock(GMutex* mutex) {
m = mutex;
g_mutex_lock(m);
}
~GMutexLock() {
g_mutex_unlock(m);
}
};
Look up "recursive mutex" or "reentrant mutex" (versus the non-recursive mutex you're using now). These enable what you want. Some folks are not fans of recursive mutexes and feel they enable messy design.
Note that a recursive mutex cannot be locked on one thread and unlocked on another.
I personally would never use recursive mutexes (especially as such).
I would do some private functions that doesn't lock mutexes and lock around them in public functions' implementations.

Callback into singleton class

I am using a singleton class with a thread that calls into the singleton. I was asked during a review why I used the this pointer instead of the singleton instance.
My code with the suggested changes.
class myClass : public threadWrapper
{
public:
static myClass& instance()
{
static myClass instance;
return instance;
}
// This is the callback that I have implemented
static void callback(void *me)
{
if (me != NULL)
static_cast<myClass*>(me)->doCallback();
}
// This is the suggested callback
static void callback2(void *me)
{
instance().doCallback();
}
// caller gets instance and then calls initialise()
int initialise()
{
if (initialised)
return ERROR_ALREADY_INITIALISED;
// Initialise the class
// my thread startup call
// thread wrapper class initialisation that calls pthread_create that runs the callback method with this as a parameter
// priority is a global value that difines the relative priority of the various threads.
threadWrapper::Initialise(priority, callback, this);
initialised = true;
}
private:
myClass() : initialised(false) {;}
void doCallback(void);
bool initialised;
static const int
}
So is there any significant difference in speed between the two?
The threadWrapper is mandated in the existing code base, and I'm not allowed to use boost.
My justification was that if we needed to make this not a singleton then fewer changes would be required.
The speed difference will be pretty much nonexistent.
As for code quality, Singletons are quite horrendous and I personally would chuck out both forms, especially in a threaded environment. Assuming that it's too late for that, however.
The thing is, if you're gonna pass in a pointer to the object, why not just not make that object global in the first place? And if you are, it should at least be strongly typed. And then, you're just ... wrapping a member method in a static method? Why bother? Anyone who has a pointer to the class can just call the method on it in the first place. This is just insane.
Edit: If you're stuck with the existing design, then the second version is definitely better than the first and no slower. Even if you have existing code that depends on the Singleton, then it's absolutely better to refactor what you can to not depend on it.