Emulate C# lock statement in C++ - c++

Intro: For synchronization, C# offers the System.Threading.Monitorclass, offering thread synchronization routines such as Enter(), Exit(), TryEnter() and alike.
Furthermore, there is the lock statement that makes sure a lock gets destroyed when a critical code block is left, either by normal execution flow or by an exception:
private static readonly obj = new Object();
lock(obj) {
...
}
Problem: In C++, for this purpose, we got the RAII wrappers std::lock_guard and std::unique_lock that are not applied to Monitor classes but to types fulfilling the Lockable concept. However, I consider this approach syntactically weaker than the way C# implemented it for several reasons:
You pollute the local scope with a variable name that cannot be reused. This can be countered by adding new scopes like
{
std::unique_lock<std::mutex> lck{ mtx };
...
}
But I find this notation rather awkward-looking. What troubles me even more that this is valid C++:
std::unique_lock<std::mutex>{ mtx ]; // note there is no name to the lock!
...
So by forgetting to give a proper name to the lock guard, this statement will be interpreted as a variable declaration named "mtx" of type std::unique_lock<std::mutex>, without having anything locked!
I want to implement something like the lock statement from C# in C++. In C++17, this can be accomplished very easily:
#define LOCK(mutex) if(std::lock_guard<decltype(mutex)> My_Lock_{ mutex }; true)
std::mutex mtx;
LOCK(mtx) {
...
}
Q: How can I implement this in C++11/14?

Putting aside the "should you do this", here's how:
While it's not quite the same, since it requires a semi-colon, it's near enough that I feel I may present it. This pure C++14 solution basically just defines the macro to start a lambda which is immediately executed:
template<typename MTX>
struct my_lock_holder {
MTX& mtx;
my_lock_holder(MTX& m) : mtx{m} {}
};
template<typename MTX, typename F>
void operator+(my_lock_holder<MTX>&& h, F&& f) {
std::lock_guard<MTX> guard{h.mtx};
std::forward<F>(f)();
}
#define LOCK(mtx) my_lock_holder<decltype(mtx)>{mtx} + [&]
The my_lock_holder just nabs the mutex reference for later, and allows us to overload operator+. The idea is that the operator creates the guard and execute the lambda. As you can see the macro defines a default reference capture, so that lambda will be able to reference anything in the enclosing scope. Then it's pretty much straight forward:
std::mutex mtx;
LOCK(mtx) {
}; // Note the semi-colon
And you can see it build live.

Inspired by StoryTeller's great idea, I think I found a viable solution myself, despite being somewhat a "hack":
template <typename T>
struct Weird_lock final : private std::lock_guard<T> {
bool flip;
Weird_lock(T& m) : std::lock_guard<T>{ m }, flip{ true } { }
operator bool() noexcept {
bool old = flip;
flip = false;
return old;
}
};
#define LOCK(mutex) for(Weird_lock<decltype(mutex)> W__l__{ mutex }; W__l__;)
The good thing is that it doesn't need a semicolon in the end. The bad is the need for an additional bool, but from what I see in godbolt.org, the compiler optimizes this out anyways.

I suggest you do:
#define UNIQUE_NAME(name) name##__COUNTER__
#define LOCK(mutex) std::lock_guard<decltype(mutex)> UNIQUE_NAME(My_Lock){ mutex };
Using the
COUNTER preprocessor symbol will generate a unique variable name that you simply don't care about.

Related

Using boost::mutex as a private member of class

I have a class that contains a boost::mutex as a private member. It becomes locked when you call one of its public functions and unlocks when the function exits. This is to provide synchronous access to the object's internals.
class StringDeque
{
boost::mutex mtx;
std::deque<string> string_deque;
public:
StringDeque() { }
void addToDeque(const string& str_to_add)
{
boost::lock_guard<boost::mutex> guard(mtx);
string_deque.push(str_to_add);
}
string popFromDeque()
{
boost::lock_guard<boost::mutex> guard(mtx);
string popped_string = string_deque.front();
string_deque.pop();
return popped_string;
}
};
This class isn't meant to be particularly useful but I am just playing around with mutexes and threads.
I have a main() that also has another function defined that pops strings from the class and prints them in a thread. It will repeat this 10 times and then return from the function. Once again, this is purely for testing purposes. It looks like this:
void printTheStrings(StringDeque& str_deque)
{
int i = 0;
while(i < 10)
{
string popped_string = str_deque.popFromDeque();
if(popped_string.empty())
{
sleep(1);
continue;
}
cout << popped_string << endl;
++i;
}
}
int main()
{
StringDeque str_deque;
boost::thread the_thread(printTheStrings, str_deque);
str_deque.addToDeque("Say your prayers");
str_deque.addToDeque("Little One");
str_deque.addToDeque("And Don't forget My Son");
str_deque.addToDeque("To include everyone");
str_deque.addToDeque("I tuck you in");
str_deque.addToDeque("Warm within");
str_deque.addToDeque("Keep you free from sin");
str_deque.addToDeque("Until the sandman he comes");
str_deque.addToDeque("Sleep with one eye open");
str_deque.addToDeque("Gripping your pillow tight");
the_thread.join();
}
The error I keep getting is that boost::mutex is noncopyable. The printTheStrings() function takes a reference so I am a little confused as to why this is trying to copy the object.
I have read up a bit on this and one solution I keep reading is to make the boost::mutex a static private member of the object. However, this defeats the purpose of my mutex since I want it to be on an object-by-object basis rather than a class variable.
Is this just bad use of mutexes? Should I just be rethinking this entire application?
EDIT:
I just discovered condition_variable which should serve my purpose a lot better to have the thread wait until there is something actually in the deque before waking up to pop from the deque and print it. All the examples that I see define these mutexes and condition_variable objects at a global scope. This seems very... not object-oriented in my opinion. Even the examples straight from Boost themselves show that it is done in this way. Is this really how other people use these objects?
You are correct that printToString takes the StringQueue by reference. Your problem is that boost::thread take its arguments by value. To force it to take the arguments by reference you will need to modify things to:
boost::thread the_thread(printTheStrings, boost::ref(str_deque));
As an aside, from C++11 onwards, threads are part of the standard library. You should probably use std::thread instead

Mutexes and lambda functions in c++

When dealing with concurrency problems I often use std::unique_lock<std::mutex> and std::lock_guard<std::mutex>, no problem with both.
I also extended std::mutex to be able to use it as follow:
mutex.protect([](){
// my protected code here
}) ;
It locks the mutex and releases it around the lambda call.
Is such a similar behavior already implemented inside boost or the standard library?
Boost Thread has this: http://www.boost.org/doc/libs/1_58_0/doc/html/thread/synchronization.html#thread.synchronization.with_lock_guard
You can use it like you'd expect:
std::mutex mx;
boost::with_lock_guard(mx, []{
// protected stuff
});
It even supports the usual INVOKE semantics:
int foo(int,double) { return 42; }
// ...
int answer = boost::with_lock_guard(mx, foo, 3, 3.14);
Manual Standard Library Only implementation
You can easily add a thing like this yourself:
template <typename M, typename F, typename... Args>
auto my_with_lock_guard(M& mx, F&& f, Args&&... args) {
std::lock_guard<M> lk(mx);
return std::forward<F>(f)(std::forward<Args>(args)...);
}
If the standard ever adopts a proposal like this you can easily swap it out.
If all you want to do is protect code in a smaller scope inside a function you don't need to extend mutex by writing your own protect function. You can just do as below, use curly braces to create a local scope, and when the scope is exited the mutex will automatically be unlocked in an exception safe way.
double process_func() {
// do some stuff
{ //start a new scope block
std::lock_guard<my_mutex> g; // mutex is locked here.
[]() { } // your lambda that needs to be protected
} // Mutex is released here.
// do more stuff
}
Of course this has the disadvantage over your custom function that,
it is difficult to maintain. Someone can come later and inject more code without knowing what they are doing.

Is this an acceptable way to lock a container using C++?

I need to implement (in C++) a thread safe container in such a way that only one thread is ever able to add or remove items from the container. I have done this kind of thing before by sharing a mutex between threads. This leads to a lot of mutex objects being littered throughout my code and makes things very messy and hard to maintain.
I was wondering if there is a neater and more object oriented way to do this. I thought of the following simple class wrapper around the container (semi-pseudo C++ code)
class LockedList {
private:
std::list<MyClass> m_List;
public:
MutexObject Mutex;
};
so that locking could be done in the following way
LockedList lockableList; //create instance
lockableList.Mutex.Lock(); // Lock object
... // search and add or remove items
lockableList.Mutex.Unlock(); // Unlock object
So my question really is to ask if this is a good approach from a design perspective? I know that allowing public access to members is frowned upon from a design perspective, does the above design have any serious flaws in it. If so is there a better way to implement thread safe container objects?
I have read a lot of books on design and C++ in general but there really does seem to be a shortage of literature regarding multithreaded programming and multithreaded software design.
If the above is a poor approach to solving the problem I have could anyone suggest a way to improve it, or point me towards some information that explains good ways to design classes to be thread safe??? Many thanks.
I would rather design a resourece owner that locks a mutex and returns an object that can be used by the thread. Once the thread has finished with it and stops using the object the resource is automatically returned to its owner and the lock released.
template<typename Resource>
class ResourceOwner
{
Lock lock;
Resource resource;
public:
ResourceHolder<Resource> getExclusiveAccess()
{
// Let the ResourceHolder lock and unlock the lock
// So while a thread holds a copy of this object only it
// can access the resource. Once the thread releases all
// copies then the lock is released allowing another
// thread to call getExclusiveAccess().
//
// Make it behave like a form of smart pointer
// 1) So you can pass it around.
// 2) So all properties of the resource are provided via ->
// 3) So the lock is automatically released when the thread
// releases the object.
return ResourceHolder<Resource>(lock, resource);
}
};
The resource holder (not thought hard so this can be improved)
template<typename Resource>
class ResourceHolder<
{
// Use a shared_ptr to hold the scopped lock
// When first created will lock the lock. When the shared_ptr
// destroyes the scopped lock (after all copies are gone)
// this will unlock the lock thus allowding other to use
// getExclusiveAccess() on the owner
std::shared_ptr<scopped_lock> locker;
Resource& resource; // local reference on the resource.
public:
ResourceHolder(Lock& lock, Resource& r)
: locker(new scopped_lock(lock))
, resource(r)
{}
// Access to the resource via the -> operator
// Thus allowing you to use all normal functionality of
// the resource.
Resource* operator->() {return &resource;}
};
Now a lockable list is:
ResourceOwner<list<int>> lockedList;
void threadedCode()
{
ResourceHolder<list<int>> list = lockedList.getExclusiveAccess();
list->push_back(1);
}
// When list goes out of scope here.
// It is destroyed and the the member locker will unlock `lock`
// in its destructor thus allowing the next thread to call getExclusiveAccess()
I would do something like this to make it more exception-safe by using RAII.
class LockedList {
private:
std::list<MyClass> m_List;
MutexObject Mutex;
friend class LockableListLock;
};
class LockableListLock {
private:
LockedList& list_;
public:
LockableListLock(LockedList& list) : list_(list) { list.Mutex.Lock(); }
~LockableListLock(){ list.Mutex.Unlock(); }
}
You would use it like this
LockableList list;
{
LockableListLock lock(list); // The list is now locked.
// do stuff to the list
} // The list is automatically unlocked when lock goes out of scope.
You could also make the class force you to lock it before doing anything with it by adding wrappers around the interface for std::list in LockableListLock so instead of accessing the list through the LockedList class, you would access the list through the LockableListLock class. For instance, you would make this wrapper around std::list::begin()
std::list::iterator LockableListLock::begin() {
return list_.m_List.begin();
}
and then use it like this
LockableList list;
LockableListLock lock(list);
// list.begin(); //This is a compiler error so you can't
//access the list without locking it
lock.begin(); // This gets you the beginning of the list
Okay, I'll state a little more directly what others have already implied: at least part, and quite possibly all, of this design is probably not what you want. At the very least, you want RAII-style locking.
I'd also make the locked (or whatever you prefer to call it) a template, so you can decouple the locking from the container itself.
// C++ like pesudo-code. Not intended to compile as-is.
struct mutex {
void lock() { /* ... */ }
void unlock() { /* ... */ }
};
struct lock {
lock(mutex &m) { m.lock(); }
~lock(mutex &m) { m.unlock(); }
};
template <class container>
class locked {
typedef container::value_type value_type;
typedef container::reference_type reference_type;
// ...
container c;
mutex m;
public:
void push_back(reference_type const t) {
lock l(m);
c.push_back(t);
}
void push_front(reference_type const t) {
lock l(m);
c.push_front(t);
}
// etc.
};
This makes the code fairly easy to write and (for at least some cases) still get correct behavior -- e.g., where your single-threaded code might look like:
std::vector<int> x;
x.push_back(y);
...your thread-safe code would look like:
locked<std::vector<int> > x;
x.push_back(y);
Assuming you provide the usual begin(), end(), push_front, push_back, etc., your locked<container> will still be usable like a normal container, so it works with standard algorithms, iterators, etc.
The problem with this approach is that it makes LockedList non-copyable. For details on this snag, please look at this question:
Designing a thread-safe copyable class
I have tried various things over the years, and a mutex declared beside the the container declaration always turns out to be the simplest way to go ( once all the bugs have been fixed after naively implementing other methods ).
You do not need to 'litter' your code with mutexes. You just need one mutex, declared beside the container it guards.
It's hard to say that the coarse grain locking is a bad design decision. We'd need to know about the system that the code lives in to talk about that. It is a good starting point if you don't know that it won't work however. Do the simplest thing that could possibly work first.
You could improve that code by making it less likely to fail if you scope without unlocking though.
struct ScopedLocker {
ScopedLocker(MutexObject &mo_) : mo(mo_) { mo.Lock(); }
~ScopedLocker() { mo.Unlock(); }
MutexObject &mo;
};
You could also hide the implementation from users.
class LockedList {
private:
std::list<MyClass> m_List;
MutexObject Mutex;
public:
struct ScopedLocker {
ScopedLocker(LockedList &ll);
~ScopedLocker();
};
};
Then you just pass the locked list to it without them having to worry about details of the MutexObject.
You can also have the list handle all the locking internally, which is alright in some cases. The design issue is iteration. If the list locks internally, then operations like this are much worse than letting the user of the list decide when to lock.
void foo(LockedList &list) {
for (size_t i = 0; i < 100000000; i++) {
list.push_back(i);
}
}
Generally speaking, it's a hard topic to give advice on because of problems like this. More often than not, it's more about how you use an object. There are a lot of leaky abstractions when you try and write code that solves multi-processor programming. That is why you see more toolkits that let people compose the solution that meets their needs.
There are books that discuss multi-processor programming, though they are few. With all the new C++11 features coming out, there should be more literature coming within the next few years.
I came up with this (which I'm sure can be improved to take more than two arguments):
template<class T1, class T2>
class combine : public T1, public T2
{
public:
/// We always need a virtual destructor.
virtual ~combine() { }
};
This allows you to do:
// Combine an std::mutex and std::map<std::string, std::string> into
// a single instance.
combine<std::mutex, std::map<std::string, std::string>> mapWithMutex;
// Lock the map within scope to modify the map in a thread-safe way.
{
// Lock the map.
std::lock_guard<std::mutex> locked(mapWithMutex);
// Modify the map.
mapWithMutex["Person 1"] = "Jack";
mapWithMutex["Person 2"] = "Jill";
}
If you wish to use an std::recursive_mutex and an std::set, that would also work.

Lightweight wrapper - is this a common problem and if yes, what is its name?

I have to use a library that makes database calls which are not thread-safe. Also I occasionally have to load larger amounts of data in a background thread.
It is hard to say which library functions actually access the DB, so I think the safest approach for me is to protect every library call with a lock.
Let's say I have a library object:
dbLib::SomeObject someObject;
Right now I can do something like this:
dbLib::ErrorCode errorCode = 0;
std::list<dbLib::Item> items;
{
DbLock dbLock;
errorCode = someObject.someFunction(&items);
} // dbLock goes out of scope
I would like to simplify that to something like this (or even simpler):
dbLib::ErrorCode errorCode =
protectedCall(someObject, &dbLib::SomeObject::someFunction(&items));
The main advantage of this would be that I won't have to duplicate the interface of dbLib::SomeObject in order to protect each call with a lock.
I'm pretty sure that this is a common pattern/idiom but I don't know its name or what keywords to search for. (Looking at http://www.vincehuston.org/dp/gof_intents.html I think, it's more an idiom than a pattern).
Where do I have to look for more information?
You could make protectedCall a template function that takes a functor without arguments (meaning you'd bind the arguments at the call-site), and then creates a scoped lock, calls the functor, and returns its value. For example something like:
template <typename Ret>
Ret protectedCall(boost::function<Ret ()> func)
{
DbLock lock;
return func();
}
You'd then call it like this:
dbLib::ErrorCode errorCode = protectedCall(boost::bind(&dbLib::SomeObject::someFunction, &items));
EDIT. In case you're using C++0x, you can use std::function and std::bind instead of the boost equivalents.
In C++0x, you can implement some form of decorators:
template <typename F>
auto protect(F&& f) -> decltype(f())
{
DbLock lock;
return f();
}
usage:
dbLib::ErrorCode errorCode = protect([&]()
{
return someObject.someFunction(&items);
});
From your description this would seem a job for Decorator Pattern.
However, especially in the case of resources, I wouldn't recommend using it.
The reason is that in general these functions tend to scale badly, require higher level (less finegrained) locking for consistency, or return references to internal structures that require the lock to stay locked until all information is read.
Think, e.g. about a DB function that calls a stored procedure that returns a BLOB (stream) or a ref cursor: the streams should not be read outside of the lock.
What to do?
I recommend instead to use the Facade Pattern. Instead of composing your operations directly in terms of DB calls, implement a facade that uses the DB layer; This layer could then manage the locking at exactly the required level (and optimize where needed: you could have the facade be implemented as a thread-local Singleton, and use separate resources, obviating the need for locks, e.g.)
The simplest (and still straightforward) solution might be to write a function which returns a proxy for the object. The proxy does the locking and overloads -> to allow calling the object. Here is an example:
#include <cstdio>
template<class T>
class call_proxy
{
T &item;
public:
call_proxy(T &t) : item(t) { puts("LOCK"); }
T *operator -> () { return &item; }
~call_proxy() { puts("UNLOCK"); }
};
template<class T>
call_proxy<T> protect(T &t)
{
return call_proxy<T>(t);
}
Here's how to use it:
class Intf
{
public:
void function()
{
puts("foo");
}
};
int main()
{
Intf a;
protect(a)->function();
}
The output should be:
LOCK
foo
UNLOCK
If you want the lock to happen before the evaluation of the arguments, then can use this macro:
#define PCALL(X,APPL) (protect(X), (X).APPL)
PCALL(x,x.function());
This evaluates x twice though.
This article by Andrei Alexandrescu has a pretty interesting article how to create this kind of thin wrapper and combine it with dreaded volatile keyword for thread safety.
Mutex locking is a similar problem. It asked for help here: Need some feedback on how to make a class "thread-safe"
The solution I came up with was a wrapper class that prevents access to the protected object. Access can be obtained via an "accessor" class. The accessor will lock the mutex in its constructor and unlock it on destruction. See the "ThreadSafe" and "Locker" classes in Threading.h for more details.

Developing C++ concurrency library with "futures" or similar paradigm

I'm working on a C++ project that needs to run many jobs in a threadpool. The jobs are failure-prone, which means that I need to know how each job terminated after it completes. Being a Java programmer for the most part, I like the idea of using "futures" or a similar paradigm, akin to the various classes in Java's util.concurrent package.
I have two questions: first, does something like this already exist for C++ (I haven't found anything in Boost, but maybe I'm not looking hard enough); and second, is this even a sane idea for C++?
I found a brief example of what I'm trying to accomplish here:
http://www.boostcookbook.com/Recipe:/1234841
Does this approach make sense?
Futures are both present in the upcoming standard (C++0x) and inside boost. Note that while the main name future is the same, you will need to read into the documentation to locate other types and to understand the semantics. I don't know Java futures, so I cannot tell you where they differ, if they do.
The library in boost was written by Anthony Williams, that I believe was also involved in the definition of that part of the standard. He has also written C++ Concurrency in Action, that includes a good description of futures, tasks, promises and related objects. His company also sells a complete and up to implementation of the C++0x threading libraries, if you are interested.
Boost has futures and other threading tools implemented.
Note that when you call the get() method on a boost::unique_future it will re-throw any exception that might have been stored inside it during asynchronous execution.
I would suggest you do something like:
#pragma once
#include <tbb/concurrent_queue.h>
#include <boost/thread.hpp>
#include <boost/noncopyable.hpp>
#include <functional>
namespace internal
{
template<typename T>
struct move_on_copy
{
move_on_copy(const move_on_copy<T>& other) : value(std::move(other.value)){}
move_on_copy(T&& value) : value(std::move(value)){}
mutable T value;
};
template<typename T>
move_on_copy<T> make_move_on_copy(T&& value)
{
return move_on_copy<T>(std::move(value));
}
}
class executor : boost::noncopyable
{
boost::thread thread_;
tbb::concurrent_bounded_queue<std::function<void()>> execution_queue_;
template<typename Func>
auto create_task(Func&& func) -> boost::packaged_task<decltype(func())> // noexcept
{
typedef boost::packaged_task<decltype(func())> task_type;
auto task = task_type(std::forward<Func>(func));
task.set_wait_callback(std::function<void(task_type&)>([=](task_type& my_task) // The std::function wrapper is required in order to add ::result_type to functor class.
{
try
{
if(boost::this_thread::get_id() == thread_.get_id()) // Avoids potential deadlock.
my_task();
}
catch(boost::task_already_started&){}
}));
return std::move(task);
}
public:
explicit executor() // noexcept
{
thread_ = boost::thread([this]{run();});
}
~executor() // noexcept
{
execution_queue_.push(nullptr); // Wake the execution thread.
thread_.join();
}
template<typename Func>
auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept
{
// Create a move on copy adaptor to avoid copying the functor into the queue, tbb::concurrent_queue does not support move semantics.
auto task_adaptor = internal::make_move_on_copy(create_task(func));
auto future = task_adaptor.value.get_future();
execution_queue_.push([=]
{
try{task_adaptor.value();}
catch(boost::task_already_started&){}
});
return std::move(future);
}
template<typename Func>
auto invoke(Func&& func) -> decltype(func()) // noexcept
{
if(boost::this_thread::get_id() == thread_.get_id()) // Avoids potential deadlock.
return func();
return begin_invoke(std::forward<Func>(func), prioriy).get();
}
private:
void run() // noexcept
{
while(true)
{
std::function<void()> func;
execution_queue_.pop(func);
if(!func)
break;
func();
}
}
};
C++ templates are less restrictive than Java Generics so 'Future's could readily be ported with them and thread synchronization primitives. As for existing libraries which support such a mechanism, hopefully someone else knows of one.