C++ passing a mutex to a member variable in the constructor - c++

I have a problem with passing a mutex to my class. I have a class named Test with the a member variable called m_Mutex. In the constructor I want to transfer the parameter mutex to m_Mutex.
My class:
#include <mutex>
class Test
{
public:
Test(mutex &mtx) :
m_Mutex(mtx)
{
}
private:
mutex m_Mutex;
};
My main:
int main()
{
mutex mutex1;
Test t(mutex1);
return 0;
}
Error:
function "std::mutex::mutex(const std::mutex &)" (declared at line 88
of "c:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include\mutex")
cannot be referenced -- it is a deleted function
Why am I getting this error and how can I fix it that I am able to pass the mutex?

In short terms: you can't. Mutexes are neither copyable nor movable. And they aren't for a good reason. If however you want to achieve this nontheless, you might pass it by using a unique_ptr:
class A {
unique_ptr<mutex> mutexPtr;
A(unique_ptr<mutex> ptr) : mutexPtr(std::move(ptr)) { }
};
A a{std::make_unique<mutex>()};
Note that if you want to share the mutex between different objects, you should use shared_ptr or weak_ptr instead.

In the constructor I want to transfer the parameter mutex to m_Mutex
Unfortunately you can't. std::mutex is not copyable and not moveable. One thing you can do if you want to declare the mutex somewhere else is to store a reference to the mutex like
class Test
{
public:
Test(mutex &mtx) :
m_Mutex(mtx)
{
}
private:
mutex& m_Mutex;
};

#include <mutex>
class Test
{
public:
Test(std::mutex &mtx) :
m_Mutex(mtx)
{
}
private:
std::mutex &m_Mutex; // note the "&"
};
int main()
{
std::mutex mutex1;
Test t(mutex1);
return 0;
}

Just keep mutex inside your class (probably as static member) and if you need to allow other classes to use it provide access:
class Test
{
public:
Test() {}
std::mutex &mux() { return m_Mutex; }
private:
mutex m_Mutex;
};
or even this:
class Test {
public:
using lock_t = std::scoped_lock<std::mutex>;
Test() {}
lock_t lock() { return lock_t( m_Mutex ); }
private:
mutex m_Mutex;
};
usage:
Test t;
{
auto lock = t.lock();
// object t is locked till end of the block
}

Just make it a reference
Your mutex must be the same for all instances of your class, if it's not the case the lock you do in one instance of your class won't be active for the other one.
#include <mutex>
#include <iostream>
using namespace std;
class Test
{
public:
Test(mutex &mtx) :
m_Mutex(mtx)
{
m_Mutex.lock();
i++;
cout << "Test " <<i<<endl;
m_Mutex.unlock();
}
private:
mutex& m_Mutex;
static int i;
};
int Test::i =0;
int main()
{
mutex mutex1;
Test t1(mutex1);
Test t2(mutex1);
return 0;
}
see it live : https://wandbox.org/permlink/6YJFG3MI7m7RbfoL

Related

Accessor function for std::mutex

There are two classes. Class A has a private member std::mutex m_. Class B has an instance of class A as its member.
The goal is to let class B to be able to use m_ (which is in class A).
I tried adding an accessor method in class A as below, but it gives error no matching function for call to 'std::unique_lock<std::mutex>::unique_lock(std::mutex)'.
Is above error because std::mutex is non-copyable?
What is the suggested way to expose the std::mutex in this case?
class A {
public:
// does not work
std::mutex getMutex() {
return m_;
}
private:
std::mutex m_;
}
class B {
A a;
void someMethod() {
...
std::unique_lock<std::mutex> lock(a.m_);
...
}
}
Is above error because std::mutex is non-copyable?
That is correct. A std::mutex cannot be copied or moved.
What is the suggested way to expose the std::mutex in this case?
In this case, you can just return by reference like
std::mutex& getMutex() {
return m_;
}
and use it like
std::unique_lock<std::mutex> lock(a.getMutex());

Passing mutex reference from main to a class

I need to work with the same mutex and unique_lock across the main function and class instances. However, I am having trouble assigning the mutex/unique_lock address to a class member variable (that is a mutex&).
This is what I have:
Worker.h
class Worker
{
private:
std::mutex &m_mu;
std::unique_lock<std::mutex> &locker;
public:
void start(std::mutex &mu, std::unique_lock<std::mutex> &locker);
};
Worker.cpp
void Worker::start(std::mutex &mu, std::unique_lock<std::mutex> &locker)
{
this->mu = mu; // error
this->locker = locker; // error
}
I tried doing this->mu(mu); but that doesn't work either. Is there anything I can do to make this work?
Thanks.
You need to pass the mutex reference when you construct your class.
Worker::Worker(std::mutex &mu, std::unique_lock<std::mutex> &locker)
:m_mu(mu), locker(locker)
{}
That's the only place you can initialize a reference. Once it's constructed, you cannot change what it references.
Why do you need the locker? The mutex makes the synchronization, the lock is just a RAII object to ease acquiring the mutex.
You don't need to pass the lock object to the function. As long as the class is referring to the correct mutex you can lock the mutex inside the function like this:
class Worker
{
private:
std::mutex& m_mu;
public:
Worker(std::mutex& mu): m_mu(mu) {} // bind reference during initialization
void start();
};
// Worker.cpp
void Worker::start()
{
std::unique_lock<std::mutex> locker(m_mu); // lock the shared resource
// Do something with it here
}
int main()
{
std::mutex mu;
std::vector<Worker> workers(4, Worker(std::ref(mu)));
// etc...
}

using callbacks with threads

Modified to explain better the problem:
I wish to pass a callback function from one class to another , from class1 to class2. I don't want class2 to know anything about class1.
My below code works fine, but I would like to involve using different threads here. The code has been simplified very much by excluding the separate cpp files for the classes etc. but hopefully I get my idea across.
I would like class1 to be running some thread calling different member functions of class1 and then have class2 calling its member functions, hence the function that handles the callback from class1.
I'm not sure how to implement this. If there is a thread already running in class2 that is calling "FuncToExecuteCallback". How can I register the callback from the different thread running in class1. Or should I just start a thread running inside "FuncToExecuteCallback" when it is called.
Any help is much appreciated . Thanks
// class which contains callback to be sent to another class
class class1
{
public:
class1(class2& d);
// call back function to be passed elsewhere
void MyCallBack()
{
cout<<"Inside CallBack Function!!"<<endl;
}
void RegisterCallback()
{
d.FuncToExecuteCallback(std::bind(&class1::MyCallBack, this));
}
void CheckValues()
{
//some code
}
private:
class2& d;
};
// class which handles the callback
class class2
{
public:
bool mySignal = false;
typedef std::function<void(void)> funcType;
void FuncToExecuteCallback( funcType f)
{
//This function should be running in a separate thread
for (;;)
{
if (mySignal == true)
f();
}
};
// main function
int main(int argc, char *argv[])
{
class2 c2;
std::thread th1
{
[&]{
class1 c1{c2};
c1.RegisterCallback(); // I'd like a separate thread to be spawn here that would call FuncToExecuteCallback from class2
for (;;)
{
c1.CheckValues();
// execute more functions from class1 ....
// ...
}
};
}
Just add a mutex to your code:
#include <mutex>
class class2;
class class1{
public:
class1(class2 &c2): m_c2{c2}{}
void func(){}
void RegisterCallback();
private:
class2 &m_c2;
};
class class2{
public:
template<typename Func>
void ExecuteFunc(Func &&f){
std::unique_lock<std::mutex> lock{m_mut};
f();
}
private:
std::mutex m_mut;
};
void class1::RegisterCallback(){
m_c2.ExecuteFunc([this]{ this->func(); });
}
Then no matter how many class1's call ExecuteFunc on the same class2 there will be no race on any data within the class2. This gives no guarantee about order of locking, though.
e.g. to run ExecuteFunc in multiple threads from main:
#include <thread>
#include "myclasses.hpp"
int main(int argc, char *argv[]){
myclass2 c2;
std::thread th0{
[&]{
class1 c1{c2};
c1.RegisterCallback();
}
};
std::thread th1{
[&]{
class1 c1{c2};
c1.RegisterCallback();
}
};
th0.join();
th1.join();
}

Access class variable from std::thread

I have the following class which kicks off a new std::thread. I now want the thread to access a member variable of the class. So far I cannot work out how to do this.
In my MyThread function I want to check m_Continue.
I have tried passing in 'this' when the thread is created but I get an error:
Error 1 error C2197: 'void (__cdecl *)(void)' : too many arguments for call c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional 1152 1 MyProject.
class SingletonClass
{
public:
SingletonClass();
virtual ~SingletonClass(){};
static SingletonClass& Instance();
void DoSomething();
private:
static void MyThread();
std::thread* m_Thread;
bool m_Continue;
};
SingletonClass::SingletonClass()
{
m_Continue = true;
m_Thread= new std::thread(MyThread, this);
}
void SingletonClass::MyThread()
{
while(this->m_Continue )
{
// do something
}
}
void SingletonClass::DoSomething()
{
m_Continue = false;
}
SingletonClass& SingletonClass::Instance()
{
static SingletonClass _instance;
return _instance;
}
int _tmain(int argc, _TCHAR* argv[])
{
SingletonClass& singleton = SingletonClass::Instance();
singleton.DoSomething();
return 0;
}
How can I do this??
If you want to access this from within the thread function, then it shouldn't be static:
void MyThread();
Now you can simply pass this as the second thread constructor argument, as you tried; but, being a non-static member, you'll need to qualify its name:
m_Thread= new std::thread(&SingletonClass::MyThread, this);
Alternatively, you might find a lambda easier to read:
m_Thread= new std::thread([this]{MyThread();});
But you shouldn't muck around with pointers and new like that; make the member variable a thread object and initialise it in the initialiser list:
SingletonClass::SingletonClass() :
m_Continue(true), m_Thread([this]{MyThread();})
{}
making sure to declare m_Thread after any other members that it accesses; and make sure you stop and join the thread in the destructor, or earlier.
Finally, m_Continue should be std::atomic<bool> in order to set it on one thread and read it on another with well-defined behaviour.
Replace
static void MyThread();
with
void MyThread();
as
this cannot be access within static method.
You can access the member variable if it is public or you may make have a method like "bool shallContinue()" which returns m_Continue.
Now how do you do this. Check the below modified snippet:
static void SingletonClass::MyThread(SingleTonClass *arg)
{
while(arg->shallContinue() )
{
// do something
}
}
Below a complete example:
#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
class A
{
public:
A(int x) : a(x)
{
thr = new thread(myThread, this);
}
static void myThread(A *arg)
{
arg->show();
}
void show()
{
cout << a << endl;
}
private:
int a;
thread *thr;
};
int main()
{
A a(1);
sleep(2);
return 0;
}

Select mutex or dummy mutex at runtime

I have a class that is shared between several projects, some uses of it are single-threaded and some are multi-threaded. The single-threaded users don't want the overhead of mutex locking, and the multi-threaded users don't want to do their own locking and want to be able to optionally run in "single-threaded mode." So I would like to be able to select between real and "dummy" mutexes at runtime.
Ideally, I would have a shared_ptr<something> and assign either a real or fake mutex object. I would then "lock" this without regard to what's in it.
unique_lock<something> guard(*mutex);
... critical section ...
Now there is a signals2::dummy_mutex but it does not share a common base class with boost::mutex.
So, what's an elegant way to select between a real mutex and a dummy mutex (either the one in signals2 or something else) without making the lock/guard code more complicated than the example above?
And, before you point out the alternatives:
I could select an implementation at compile time, but preprocessor macros are ugly and maintaining project configurations is painful for us.
Users of the class in a multi-threaded environment do not want to take on the responsibility of locking the use of the class rather than having the class do its own locking internally.
There are too many APIs and existing usages involved for a "thread-safe wrapper" to be a practical solution.
How about something like this?
Its untested but should be close to OK.
You might consider making the template class hold a value rather than a pointer
if your mutexes support the right kinds of constructions. Otherwise you could specialise the MyMutex class to get value behaviour.
Also it's not being careful about copying or destruction .. I leave that as an exercise to the reader ;) ( shared_ptr or storing a value rather than a pointer should fix this)
Oh and the code would be nicer using RAII rather than explicit lock/unlock... but that's a different question.I assume thats what the unique_lock in your code does?
struct IMutex
{
virtual ~IMutex(){}
virtual void lock()=0;
virtual bool try_lock()=0;
virtual void unlock()=0;
};
template<typename T>
class MyMutex : public IMutex
{
public:
MyMutex(T t) : t_(t) {}
void lock() { t_->lock(); }
bool try_lock() { return t_->try_lock(); }
void unlock() { t_->unlock(); }
protected:
T* t_;
};
IMutex * createMutex()
{
if( isMultithreaded() )
{
return new MyMutex<boost::mutex>( new boost::mutex );
}
else
{
return new MyMutex<signal2::dummy_mutex>( new signal2::dummy_mutex );
}
}
int main()
{
IMutex * mutex = createMutex();
...
{
unique_lock<IMutex> guard( *mutex );
...
}
}
Since the two mutex classes signals2::dummy_mutex and boost::mutex don't share a common base class you could use something like "external polymorphism" to allow to them to be treated polymorphically. You'd then use them as locking strategies for a common mutex/lock interface. This allows you to avoid using "if" statements in the lock implementation.
NOTE: This is basically what Michael's proposed solution implements. I'd suggest going with his answer.
Have you ever heard about Policy-based Design ?
You can define a Lock Policy interface, and the user may choose which policy she wishes. For ease of use, the "default" policy is precised using a compile-time variable.
#ifndef PROJECT_DEFAULT_LOCK_POLICY
#define PROJECT_DEFAULT_LOCK_POLICY TrueLock
#endif
template <class LP = PROJECT_DEFAULT_LOCK_POLICY>
class MyClass {};
This way, your users can choose their policies with a simple compile-time switch, and may override it one instance at a time ;)
This is my solution:
std::unique_lock<std::mutex> lock = dummy ?
std::unique_lock<std::mutex>(mutex, std::defer_lock) :
std::unique_lock<std::mutex>(mutex);
Is this not sufficient?
class SomeClass
{
public:
SomeClass(void);
~SomeClass(void);
void Work(bool isMultiThreaded = false)
{
if(isMultiThreaded)
{
lock // mutex lock ...
{
DoSomething
}
}
else
{
DoSomething();
}
}
};
In general, a mutex is only needed if the resource is shared between multiple processes. If an instance of the object is unique for a (possibly multi-threaded) process, then a Critical Section is often more appropriate.
In Windows, the single-threaded implementation of a Critical Section is a dummy one. Not sure what platform you are using.
Just FYI, here's the implementation I ended up with.
I did away with the abstract base class, merging it with the no-op "dummy" implementation. Also note the shared_ptr-derived class with an implicit conversion operator. A little too tricky, I think, but it lets me use shared_ptr<IMutex> objects where I previously used boost::mutex objects with zero changes.
header file:
class Foo {
...
private:
struct IMutex {
virtual ~IMutex() { }
virtual void lock() { }
virtual bool try_lock() { return true; }
virtual void unlock() { }
};
template <typename T> struct MutexProxy;
struct MutexPtr : public boost::shared_ptr<IMutex> {
operator IMutex&() { return **this; }
};
typedef boost::unique_lock<IMutex> MutexGuard;
mutable MutexPtr mutex;
};
implementation file:
template <typename T>
struct Foo::MutexProxy : public IMutex {
virtual void lock() { mutex.lock(); }
virtual bool try_lock() { return mutex.try_lock(); }
virtual void unlock() { mutex.unlock(); }
private:
T mutex;
};
Foo::Foo(...) {
mutex.reset(single_thread ? new IMutex : new MutexProxy<boost::mutex>);
}
Foo::Method() {
MutexGuard guard(mutex);
}
Policy based Option:
class SingleThreadedPolicy {
public:
class Mutex {
public:
void Lock() {}
void Unlock() {}
bool TryLock() { return true; }
};
class ScopedGuard {
public:
ScopedGuard(Mutex& mutex) {}
};
};
class MultithreadingPolicy {
public:
class ScopedGuard;
class Mutex {
friend class ScopedGuard;
private:
std::mutex mutex_;
public:
void Lock() {
mutex_.lock();
}
void Unlock() {
mutex_.unlock();
}
bool TryLock() {
return mutex_.try_lock();
}
};
class ScopedGuard {
private:
std::lock_guard<std::mutex> lock_;
public:
ScopedGuard(Mutex& mutex) : lock_(mutex.mutex_) {}
};
};
Then it can be used as follows:
template<class ThreadingPolicy = SingleThreadedPolicy>
class MyClass {
private:
typedef typename ThreadingPolicy::Mutex Mutex;
typedef typename ThreadingPolicy::ScopedGuard ScopedGuard;
Mutex mutex_;
public:
void DoSomething(){
ScopedGuard guard(mutex_);
std::cout<<"Hello World"<<std::endl;
}
};