I have a std::deque<std::reference_wrapper<MyType>> mydeque. I need a function that returns the front value (as a plain reference) and pops it from the queue. As std::deque are not thread safe, access should be protected (I'm using OpenMP).
I came up with the ugly code below. It looks very bad having such advanced structures and then falling back to a raw pointer.
MyType & retrieve() {
MyType* b;
#pragma omp critical(access_mydeque)
{
b = &(mydeque.front().get());
mydeque.pop_front();
}
return *b;
}
The problem is that I cannot return within the critical section, but I also cannot declare a reference(_wrapper) before the critical section (because it must be assigned to something)... Is there a way to solve this?
Any solution I can think of involves using an omp_lock_t instead of the critical construct and a RAII class managing the omp_lock_t ownership:
class LockGuard {
public:
explicit LockGuard(omp_lock_t& lock) : m_lock(lock){
omp_set_lock(&m_lock);
}
~LockGuard() {
omp_unset_lock(&m_lock);
}
private:
omp_lock_t& m_lock;
};
Then you can either modify the code you already have into something like:
MyType & retrieve() {
LockGuard guard(mydeque_lock);
auto b = mydeque.front();
mydeque.pop_front();
return b;
}
or better, write your own thread-safe container that aggregates the lock and the std::deque:
template<class T>
class MtLifo {
public:
MtLifo() {
omp_init_lock(&m_lock);
}
typename std::deque<T>::reference front_and_pop() {
LockGuard guard(m_lock);
auto b = m_stack.front();
m_stack.pop_front();
return b;
}
void push_front(const T& value) {
LockGuard guard(m_lock);
m_stack.push_front(value);
}
~MtLifo() {
omp_destroy_lock(&m_lock);
}
private:
std::deque<T> m_stack;
omp_lock_t m_lock;
}
You could simply use TBB's parallel data structures https://software.intel.com/en-us/node/506076 (though since there is no concurrent_deque they may not be perfect for you :-( ).
They do not require that you also use TBB to describe the parallelism aspects of your code, so can be mixed into an OpenMP code. (Of course, since you're using C++ you might find TBB's approach to scalable, composable, parallelism more friendly than OpenMP's, but that's a separable decision).
Related
Related to this question, I need a mutex that works across std implementations, or a way to atomically write and read a pointer. One thread is spawned by code compiled with mingw-w64 and the other one is Visual Studio 2019 code in a static/dynamic library.
Export from your main executable (mingw-w64) to your DLL (VC++) - compiled with separate compilers - a synchronization/mutex "handle" (an opaque pointer, typically, though it can be an index into something too) and a pair of C-style functions (if you want, you can wrap them into classes like std::mutex and std::lock, exposing the same API - that'd be the safest thing to do) lock and unlock that take that handle. They can be just as bare as that, or they might include additional functionality like timeout, or try-lock - these are quite useful but not required. You can also export handle_t create() and void delete(handle_t handle) functions.
The point is that the sync object itself (the mutex or whatever) is always manipulated by those indirection functions to avoid errors in usage, and these functions are, depending on the compiler (that can easily be detected by the preprocessor), backed by compiler-specific atomic operation intrinsics or CRT functions, like the perfectly fitting InterlockedCompareExchange (it works under mingw-w64 too) and its Visual C++ specific compiler intrinsic variant, or GCC's __atomic (more specifically, __atomic_compare_exchange).
struct imutex {
virtual void lock() = 0;
virtual void unlock() = 0;
virtual ~imutex(){}
};
template<class M>
struct imp_mutex: imutex {
M m;
void lock() final override { m.lock(); }
void unlock() final override { m.unlock(); }
};
struct mymutex {
using up=std::unique_ptr<imutex, void(*)(imutex*)>;
mymutex( up m_in ):m(std::move(m_in)){}
mymutex():mymutex(up(new imp_mutex<std::mutex>{}, [](imutex* m){ delete m; })) {}
void lock(){ m->lock(); }
void unlock(){ m->unlock(); }
mymutex(mymutex&&)=delete;
private:
up m;
};
this assumes ABI compatibility of vtables and std::unique_ptr, which is plausible.
If not, replace unique ptr with something custom, and replace the virtual methods with function pointers taking a void pointer.
The point is, the mutex is created and destroyed in one library's code.
Here is a pure function pointer one. It relies that a struct containing two-three ptrs has the same layout, and that thr C calling convention is the same.
Whichever library makes the mymutex, both can then use it.
struct imutex_vtable {
void (*lock)(void*) = 0;
void (*unlock)(void*) = 0;
void (*dtor)(void*)=0;
};
template<class M>
imutex_vtable const* get_imutex_vtable(){
static const imutex_vtable vtable = {
[](void* m){ static_cast<M*>(m)->lock(); },
[](void* m){ static_cast<M*>(m)->unlock(); },
[](void* m){ delete static_cast<M*>(m); }
};
return &vtable;
}
struct mymutex {
mymutex( imutex_vtable const* vt, void* pm ):vtable(vt), pv(pm){}
template<class M>
explicit mymutex(std::unique_ptr<M> m):mymutex( get_imutex_vtable<M>(), m.release() ) {}
mymutex():mymutex(std::make_unique<std::mutex>()) {}
void lock(){ vtable->lock(pv); }
void unlock(){ vtable->unlock(pv); }
~mymutex(){ vtable->dtor(pv); }
mymutex(mymutex&&)=delete;
private:
imutex_vtable const* vtable=0;
void* pv=0;
};
This is basically implementing a simple case of C++ interface inheritance using C-like implementation, then wrapping it up in classes and templates so the user won't notice.
I am looking to implement a map of simple struct with 2 writers and multiple readers. To make it thread-safe, I am currently using mutex with unique locks (my code below). There will only be insert and edit operations on the structs and no erase.
However, because write operations will be much more frequent than read operations (around ~1m write operations vs 15-20,000 read operations in the same time period), I am worried that use of unique locks will affect the performance of the read operations.
I am wondering if there is a better / simpler way to implement a simple concurrent map for my problem? For example, would it be better to lock just the struct itself rather than the entire map each time a write / read operation is performed?
I have looked into Intel TBB concurrent unordered map and Pershing's Junction map but would prefer to stick with just using the STL if it is possible.
I am using C++11 so shared_lock is not available. I contemplated using boost::shared_lock for the read operations, but I understand from this post that the cost of locking a shared_mutex is higher than that of a plain one.
EDIT: edited code post discussion in comments.
#include <mutex>
struct Foo
{
double bar1 = 0;
long bar2 = 0;
};
typedef std::shared_ptr<Foo> FooPtr;
class FooMap
{
std::mutex mMutex;
std::unordered_map<long, FooPtr> mMap;
public:
FooPtr get(long const& key)
{
return mMap[key];
}
void set(long const& key, double a, long b)
{
std::unique_lock<std::mutex> lock(mMutex);
mMap[key]->bar1 = a;
mMap[key]->bar2 = b;
}
};
Ok, I give up... I'n afraid you code has drifted a long way from my thoughts. This is what I'm really suggesting, where you write into a new instance of the shared object to create the new foo:
#include <mutex>
struct Foo
{
double bar1 = 0;
long bar2 = 0;
};
typedef std::shared_ptr<Foo> FooPtr;
typedef std::shared_ptr<const Foo> CFooPtr;
class FooMap
{
std::mutex mMutex;
std::unordered_map<long, FooPtr> mMap;
public:
CFooPtr get(long const& key)
{
auto found = mMap.find(key);
if (found == mMap.end())
{
return nullptr;
}
return found->second;
}
void set(long const& key, double a, long b)
{
FooPtr tmp = make_shared<Foo>({a,b});
{
std::unique_lock<std::mutex> lock(mMutex);
mMap[key].swap(tmp);
}
// previous entry contents are destroyed outside mutex
}
};
Here you can find design of lock-free hash map with STL only at
https://shlomisteinberg.com/2015/09/28/designing-a-lock-free-wait-free-hash-map/
Claim to be better than TBB on heavy writes.
c++ pseudocode class:
Simple class which has a member variable, and mutex to control access to it.
I'm curious about the pro's and con's of managing the data and it's access.
In a multithreaded enviroment, is it wrong to use the approach to accessing and locking the member mutex in cbMethodA()?
I've seen samples where the members are accessed directly, and it seems incorrect to do that. The class exposes access via a public method for a reason.
Also, dereferencing a mutex to then lock it doesn't seem like best practice. Any comments?
Thanks
class A
{
public:
A():val(0);
~A();
int getVal(void);
static void cbMethodA();
static void cbMethodB();
private:
Mutex m_mutex;
int val;
}
int A::getVal(){
{
int returnVal = 0;
lockMutex(m_mutex);
returnVal = m_val;
unlock(mutex);
return returnVal;
}
void A::cbMethodA(void *ptr)
{
A* ptr = static_cast<A*> (ptr);
//get val
lockMutex(ptr->m_mutex);
//read val
int tempVal = ptr->m_val;
unlockMutex(ptr->m_mutex);
//do something with data
}
void A::cbMethodB(void *ptr)
{
A* ptr = static_cast<A*> (ptr);
//get val
int tempVal = ptr->getVal();
//process val....
}
This seems like a direct application of SPOT (Single Point Of Truth), a.k.a. DRY (Don't Repeat Yourself), two names for a single important idea. You've created a function for accessing val that performs some tasks that should always go along with accessing it. Unless there is some private, implementation-specific reason to access the member field directly, you should probably use the getter method you define. That way, if you change the synchronization mechanism that protects val, you only need to update one piece of code.
I can't think of any reason why "dereferencing a mutex to lock it" would be a bad thing, repeating yourself is a bad thing.
Basically i need to do reference counting on certain resources (like an integer index) that are not inmediately equivalent to a pointer/address semantic; basically i need to pass around the resource around, and call certain custom function when the count reaches zero. Also the way to read/write access to the resource is not a simple pointer derreference operation but something more complex. I don't think boost::shared_ptr will fit the bill here, but maybe i'm missing some other boost equivalent class i might use?
example of what i need to do:
struct NonPointerResource
{
NonPointerResource(int a) : rec(a) {}
int rec;
}
int createResource ()
{
data BasicResource("get/resource");
boost::shared_resource< MonPointerResource > r( BasicResource.getId() ,
boost::function< BasicResource::RemoveId >() );
TypicalUsage( r );
}
//when r goes out of scope, it will call BasicResource::RemoveId( NonPointerResource& ) or something similar
int TypicalUsage( boost::shared_resource< NonPointerResource > r )
{
data* d = access_object( r );
// do something with d
}
Allocate NonPointerResource on the heap and just give it a destructor as normal.
Maybe boost::intrusive_ptr could fit the bill. Here's a RefCounted base class and ancillary functions that I'm using in some of my code. Instead of delete ptr you can specify whatever operation you need.
struct RefCounted {
int refCount;
RefCounted() : refCount(0) {}
virtual ~RefCounted() { assert(refCount==0); }
};
// boost::intrusive_ptr expects the following functions to be defined:
inline
void intrusive_ptr_add_ref(RefCounted* ptr) { ++ptr->refCount; }
inline
void intrusive_ptr_release(RefCounted* ptr) { if (!--ptr->refCount) delete ptr; }
With that in place you can then have
boost::intrusive_ptr<DerivedFromRefCounted> myResource = ...
Here
is a small example about the use of shared_ptr<void> as a counted handle.
Preparing proper create/delete functions enables us to use
shared_ptr<void> as any resource handle in a sense.
However, as you can see, since this is weakly typed, the use of it causes us
inconvenience in some degree...
I just got burned by a bug that is partially due to my lack of understanding, and partially due to what I think is suboptimal design in our codebase. I'm curious as to how my 5-minute solution can be improved.
We're using ref-counted objects, where we have AddRef() and Release() on objects of these classes. One particular object is derived from the ref-count object, but a common function to get an instance of these objects (GetExisting) hides an AddRef() within itself without advertising that it is doing so. This necessitates doing a Release at the end of the functional block to free the hidden ref, but a developer who didn't inspect the implementation of GetExisting() wouldn't know that, and someone who forgets to add a Release at the end of the function (say, during a mad dash of bug-fixing crunch time) leaks objects. This, of course, was my burn.
void SomeFunction(ProgramStateInfo *P)
{
ThreadClass *thread = ThreadClass::GetExisting( P );
// some code goes here
bool result = UseThreadSomehow(thread);
// some code goes here
thread->Release(); // Need to do this because GetExisting() calls AddRef()
}
So I wrote up a little class to avoid the need for the Release() at the end of these functions.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * Thread() const { return m_T; }
};
So that now I can just do this:
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC.Thread());
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}
What I don't like is that to access the thread pointer, I have to call a member function of ThreadContainer, Thread(). Is there some clever way that I can clean that up so that it's syntactically prettier, or would anything like that obscure the meaning of the container and introduce new problems for developers unfamiliar with the code?
Thanks.
use boost::shared_ptr
it is possible to define your own destructor function, such us in next example: http://www.boost.org/doc/libs/1_38_0/libs/smart_ptr/sp_techniques.html#com
Yes, you can implement operator ->() for the class, which will recursively call operator ->() on whatever you return:
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * operator -> () const { return m_T; }
};
It's effectively using smart pointer semantics for your wrapper class:
Thread *t = new Thread();
...
ThreadContainer tc(t);
...
tc->SomeThreadFunction(); // invokes tc->t->SomeThreadFunction() behind the scenes...
You could also write a conversion function to enable your UseThreadSomehow(ThreadContainer tc) type calls in a similar way.
If Boost is an option, I think you can set up a shared_ptr to act as a smart reference as well.
Take a look at ScopeGuard. It allows syntax like this (shamelessly stolen from that link):
{
FILE* topSecret = fopen("cia.txt");
ON_BLOCK_EXIT(std::fclose, topSecret);
... use topSecret ...
} // topSecret automagically closed
Or you could try Boost::ScopeExit:
void World::addPerson(Person const& aPerson) {
bool commit = false;
m_persons.push_back(aPerson); // (1) direct action
BOOST_SCOPE_EXIT( (&commit)(&m_persons) )
{
if(!commit)
m_persons.pop_back(); // (2) rollback action
} BOOST_SCOPE_EXIT_END
// ... // (3) other operations
commit = true; // (4) turn all rollback actions into no-op
}
I would recommend following bb advice and using boost::shared_ptr<>. If boost is not an option, you can take a look at std::auto_ptr<>, which is simple and probably addresses most of your needs. Take into consideration that the std::auto_ptr has special move semantics that you probably don't want to mimic.
The approach is providing both the * and -> operators together with a getter (for the raw pointer) and a release operation in case you want to release control of the inner object.
You can add an automatic type-cast operator to return your raw pointer. This approach is used by Microsoft's CString class to give easy access to the underlying character buffer, and I've always found it handy. There might be some unpleasant surprises to be discovered with this method, as in any time you have an implicit conversion, but I haven't run across any.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
operator ThreadClass *() const { return m_T; }
};
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC);
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}