If I have to write a singleton class in C++ I will be using a static variable, private constructor & a public static function that returns an object of class. However in Multithreaded environments the code will have problems. In order to avoid multiple threads access the same variable at the same time, is Boost threads best mechanism to use for synchronization? I mean for setting/unsetting a lock/mutex across the resource. Is there anything else inbuilt in C++ standard library where in I dont have to download boost, build stuff etc? I have heard of C++ Ox but dont know much.
C++98/03 have nothing to support threads at all. If you're using a C++98 or 03 compiler, you're pretty much stuck with using Boost, or something (more or less) OS-specific, such as pthreads or Win32's threading primitives.
C++11 has a reasonably complete thread support library, with mutexes, locks, thread-local storage, etc.
I feel obliged to point out, however, that it may be better to back up and do a bit more thinking about whether you need/want a Singleton at all. To put it nicely, the singleton pattern has fallen out of favor to a large degree.
Edit: Rereading this, I kind of skipped over one thing I'd intended to say: at least when I've used them, any/all singletons were fully initialized before any secondary thread was started. That renders concern over thread safety in their initialization completely moot. I suppose there could be a singleton that you can't initialize before you start up secondary threads so you'd need to deal with this, but at least right off it strikes me as a rather unusual exception that I'd deal with only when/if absolutely necessary.
For me the best way to implement a singleton using c++11 is:
class Singleton
{
public:
static Singleton & Instance()
{
// Since it's a static variable, if the class has already been created,
// It won't be created again.
// And it **is** thread-safe in C++11.
static Singleton myInstance;
// Return a reference to our instance.
return myInstance;
}
// delete copy and move constructors and assign operators
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
// Any other public methods
protected:
Singleton()
{
// Constructor code goes here.
}
~Singleton()
{
// Destructor code goes here.
}
// And any other protected methods.
}
This is a c++11 feature but with this way you can create a thread safe Singleton. According to new standard there is no need to care about this problem any more. Object initialization will be made only by one thread, other threads will wait till it complete. Or you can use std::call_once.
If you want to make a exclusive access to the singleton's resources you have to use a lock at these functions.
The different type of locks:
Using atomic_flg_lck:
class SLock
{
public:
void lock()
{
while (lck.test_and_set(std::memory_order_acquire));
}
void unlock()
{
lck.clear(std::memory_order_release);
}
SLock(){
//lck = ATOMIC_FLAG_INIT;
lck.clear();
}
private:
std::atomic_flag lck;// = ATOMIC_FLAG_INIT;
};
Using atomic:
class SLock
{
public:
void lock()
{
while (lck.exchange(true));
}
void unlock()
{
lck = true;
}
SLock(){
//lck = ATOMIC_FLAG_INIT;
lck = false;
}
private:
std::atomic<bool> lck;
};
Using mutex:
class SLock
{
public:
void lock()
{
lck.lock();
}
void unlock()
{
lck.unlock();
}
private:
std::mutex lck;
};
Just for Windows:
class SLock
{
public:
void lock()
{
EnterCriticalSection(&g_crit_sec);
}
void unlock()
{
LeaveCriticalSection(&g_crit_sec);
}
SLock(){
InitializeCriticalSectionAndSpinCount(&g_crit_sec, 0x80000400);
}
private:
CRITICAL_SECTION g_crit_sec;
};
The atomic and and atomic_flg_lck keep the thread in a spin count. Mutex just sleeps the thread. If the wait time is too long maybe is better sleep the thread. The last one "CRITICAL_SECTION" keeps the thread in a spin count until a time is consumed, then the thread goes to sleep.
How to use these critical sections?
unique_ptr<SLock> raiilock(new SLock());
class Smartlock{
public:
Smartlock(){ raiilock->lock(); }
~Smartlock(){ raiilock->unlock(); }
};
Using the raii idiom. The constructor to lock the critical section and the destructor to unlock it.
Example
class Singleton {
void syncronithedFunction(){
Smartlock lock;
//.....
}
}
This implementation is thread safe and exception safe because the variable lock is saved in the stack so when the function scope is ended (end of function or an exception) the destructor will be called.
I hope that you find this helpful.
Thanks!!
Related
I have singleton object shared between two units operating on seperate threads.
For example,
Thread A
Singleton.getInstace().incCounter();
Thread B
Singleton.getInstance().decCounter();
Is it possible to implement this atomics to be thread safe without bothering the consumers to do it in thread safe way.
Something like
static Singleton& GetInstance() {
std::scoped_lock lock(m_mtx);
static Singleton* singleton = new Singleton();
return *singleton;
}
I guess this will not work as the lock will be released after the return but incCounter and decCounter will be called without the lock.
Is it somehow possible to keep the lock active till atomic operation is completed.
Is doing a lock within the incCounter and decCounter the only solution here or in unit A and unit B only solution.
The current lock accomplishes nothing. A static function-local variable is required by the C++ standard to be initialized in exactly one thread. That is, the compiler will ensure that there can be no race conditions on its initialization. So the lock is protecting against something that can't happen.
You need to put a lock in the increment/decrement functions. And they need to lock the same mutex. Though perhaps they could increment/decrement an atomic variable, in which case you don't need a lock at all.
You could (but probably shouldn't) create a new type LockedSingleton which stores a reference to the singleton and a std::unique_lock. This would be what your GetInstance() returns. LockedSingleton would need to have its own increment/decrement functions which it forwards to its internal singleton reference, as well as any other interface functions.
class LockedSingleton
{
private:
std::unique_lock<std::mutex> lock_;
Singleton &obj_;
private: //Only friends can construct. Also, non-copyable.
LockedSingleton(std::mutex &mtx, Singleton &obj)
: lock_(mtx)
, obj_(obj)
{}
friend Singleton& GetInstance();
public:
void incCounter() {obj.incCounter();}
void decCounter() {obj.decCounter();}
};
static LockedSingleton GetInstance() {
static Singleton* singleton = new Singleton();
return LockedSingleton(m_mtx, *singleton);
}
Note that this only works in C++17 and above, due to guaranteed elision, since LockedSingleton is non-copyable.
I want to create a thread safe class containing a method to insert elements into a list.
When one of the threads destroys an instance, I want the messages in the list to be processed, while preventing other threads to insert other messages.
The idea is the following:
MyClass{
...
public:
...
void send(string s){
lock_guard<mutex> lock(m);
my_list.push_back(s);
}
~MyClass(){
lock_guard<mutex> lock(m);
for(string s:my_list)
process(s);
}
}
Is the synchronization correct?
For the method send I added the lock so that multiple threads can call it in a safe way.
As for what concerns the destructor, is there a possibility that a thread will call send between the lock release and the actual destruction of the instance? ie. is the for (and the following lock_guard destruction) the last instruction that will be executed before the actual destruction, or a race condition is possible once the destructor is executed?
You might split your class:
class MyClass
{
public:
void send(const std::string& s){
lock_guard<mutex> lock(m);
my_list.push_back(s);
}
void process_all_messages()
{
lock_guard<mutex> lock(m);
for (const string& s : my_list)
process(s);
//my_list.clear();
}
void process(const std::string& s);
// ... mutex, list, ...
};
And have a wrapper on it
class MyClassPerTHread
{
public:
explicit MyClassPerTHread(std::shared_ptr<MyClass> ptr) : ptr(ptr) {}
~MyClassPerTHread(){ ptr->process_all_messages(); }
// MyClassPerTHread(const MyClassPerTHread&);
// MyClassPerTHread(MyClassPerTHread&&);
// MyClassPerTHread& operator=(const MyClassPerTHread&);
// MyClassPerTHread& operator=(MyClassPerTHread&&);
void send(const std::string& s) { ptr->send(s); };
private:
std::shared_ptr<MyClass> ptr;
};
So in main, you create an instance of std::shared_ptr<MyClass>.
you pass it to each thread which wrap it in MyClassPerTHread.
When MyClassPerTHread is destroyed, You process the messages as expected.
You might want to adapt MyClassPerTHread for move/copy though.
You have a good intuition here; the lock_guard in the destructor isn't doing any good at all.
Here's why:
The way this is written, any calls to send() must be done before ~MyClass()'s lock_guard is created – otherwise the message won't get processed and send() could very well be using m and my_list after their destruction is complete, leading to undefined behavior. Callers of send() have no way to make sure this happens other than just making sure all calls to send() are done before ~MyClass() even starts.
This is OK. Most classes have (or should have) a requirement that clients serialize destruction. That is, clients must make sure all callers to send() are done before ~MyClass() is invoked. In fact, all standard library classes have this requirement, unless otherwise documented. Some classes deliberately don't require this; that's fine, but somewhat exotic.
This really isn't terribly hard for clients to do, fortunately; they can just use a shared_ptr or something, as suggested by Jarod42.
tl;dr:
is there a possibility that a thread will call send between the lock release and the actual destruction of the instance?
Yes! Document that it is a client error if they do this and get rid of the lock in the destructor.
I need to lock object by private mutex in some external functions. What is the best way to do this?
I want something like this
#include <thread>
#include <mutex>
class Test
{
public:
std::lock_guard<std::mutex> lockGuard()
{
return std::lock_guard<std::mutex>(mutex);
}
private:
std::mutex mutex;
};
int main()
{
Test test;
std::lock_guard<std::mutex> lock = test.lockGuard();
//...
}
But lock_guard copy contructor is deleted. How can I do something like this?
Just use std::unique_lock<std::mutex> instead. It is not copyable, but it is movable, allowing the pattern you show.
#include <thread>
#include <mutex>
class Test
{
public:
std::unique_lock<std::mutex> lockGuard()
{
return std::unique_lock<std::mutex>(mutex);
}
private:
std::mutex mutex;
};
int main()
{
Test test;
std::unique_lock<std::mutex> lock = test.lockGuard();
//...
}
std::unique_lock<std::mutex> has a broadened API relative to std::lock_guard including:
Move constructible.
Move assignable.
Swappable.
lock()
unlock()
try_lock()
try_lock_for()
try_lock_until()
release()
owns_lock()
In other words, since you can unlock and move from a unique_lock, it is not guaranteed to hold the lock on the mutex (you can check that it does with owns_lock()). In contrast an invariant of lock_guard is that it always holds the lock on the mutex.
The std::unique_lock<T> has a move constructor defined and can be used as you like, but the approach is not very successful itself.
You should review your locking granularity, usually if you can't provide internal synchronization and ask user to maintain lock while performing operations (or when you need to perform multiple operations) on an object, there is no reason to store the mutex inside the object.
If I had to store the mutex inside object, I would use some wrapper which allows me to do the following:
locking_wrapper<Test> test;
test.do_locked([] (Test & instance) {
/* The following code is guaranteed not to interleave with
* any operations performed on instance from other threads. */
// your code using instance here
});
The locking_wrapper<T> would store store an instance of an object inside and provide a reference to it while maintaining a lock on internal mutex. Relying on the compiler's ability to inline code, such approach should give no overhead above what you're trying to do in your question.
The general idea on implementing the locking_wrapper is as follows:
template<typename T>
class locking_wrapper
{
mutable std::mutex mutex;
// the object which requires external synchronization on access
T instance;
public:
/* Here we define whatever constructors required to construct the
* locking_wrapper (e.g. value-initialize the instance, take an
* instance passed by user or something different) */
locking_wrapper() = default;
locking_wrapper(const T & instance) : instance{instance} {}
// Takes a functor to be performed on instance while maintaining lock
template<typename Functor>
void do_locked(Functor && f) const {
const std::lock_guard<std::mutex> lock{mutex};
f(instance);
}
};
You may pass whatever callable-entity to do_locked as you see fit, however calling it with a lambda-expression as I've suggested previously will give it the best chances to be inlined without any overhead.
Please note that using this approach with references, movable objects or some other kind I have not yet foreseen would require some modifications to the code.
I'm trying to make a class thread safe by using a mutex.
class Container
{
private:
vector<Foo> v;
boost::mutex m;
public:
void add(Foo item)
{
m.lock();
v.push_back(item);
m.unlock();
}
};
The problem is that boost::mutex is non-copyable, so this makes Container noncopyable. Of course if I copy Container the new instance presumably doesn't need to keep the same mutex as the old one - it can have a new mutex of its own. I could write custom copy constructors for Container that do this but in reality it's a complex class and I don't want to. So how about this:
class CopyableMutex
{
private:
boost::mutex m;
public:
CopyableMutex() {}
CopyableMutex(CopyableMutex&) {} //don't copy, just create a new one
CopyableMutex& operator=(CopyableMutex&) {return *this;} //don't assign, keep it the same
void lock() {m.lock();}
void unlock() {m.unlock();}
};
...and then replacing boost::mutex in Container with CopyableMutex.
Is this a hideous thing to do? If not then am I reinventing the wheel - is there a library class that does this already?
Yes it's hideous.
The correct solution to the problem is a custom copy constructor and assignment operator for your container.
If the class is "too complex" to write a custom copy constructor for, then separate the thread-safety from the container and have base class container which doesn't contain a mutex and, perhaps, a derived class "thread safe container" which contains a mutex and has a custom copy constructor and assignment op that just call through to the automatically generated base class ones.
I believe that one of the things that doing it this way invalidates is the correct way to use mutexes these days:
void func()
{
std::lock_guard<std::mutex> lock(mtx);
// do things
}
As you can not return a mutex and so there would be no way to up-scope it to where you want to use it. The reason for the above style of usage is to prevent issues that arise when you use a lock, and then some form of unhanded exception happens prior to you unlock (ie it ensures a more reliable unlock).
I agree with other answer though, that a better way would be to just encapsulate your thread safety part and isolate it from your complex code (if possible), and then just make explicit copy constructors for that smaller class.
Currently I want to make wrapper accessor class in multithreaded environment. The purpose of the class is simple - Grab a lock on its construction and release a lock on its destruction. Other than that, it's identical to a normal pointer. Moreover, I want to prevent it from being created on heap area to ensure that the lock will be released eventually.
The inverse is fairly easy (private constructor with factory method), but I don't know that a stack-only variable is possible. Is there anyway?
Well, what about you overload operator new for your class and delcare it private?
I don't understand the problem? Any variable defined within the scope of a function is stack-only.
class Lock {
public:
Lock() {
performLock();
}
~Lock() {
performUnlock();
}
}
void foo() {
// ... Code
Lock onStackOnly;
// ... Code that is locked
}
void foo() {
// ... Code
{
Lock onStackOnly;
// ... Code that is locked
}
// This code is unlocked.
}