In the classic problem of transferring money from one bank account to another, the accepted solution (I believe) is to associate a mutex with each bank account, then lock both b
Check out Herb Sutter talk at C++ and Beyond 2012: C++ Concurrency. He shows example of Monitor Object-like implementation in C++11.
monitor m[2];
transaction([](Account &x,Account &y)
{
// Both accounts are automaticaly locked at this place.
// Do whatever operations you want to do on them.
x.money-=100;
y.money+=100;
},m[0],m[1]);
// transaction - is variadic function template, it may accept many accounts
Implementation:
LIVE DEMO
#include
#include
#include
#include
using namespace std;
typedef int Money;
struct Account
{
Money money = 1000;
// ...
};
template
T &lvalue(T &&t)
{
return t;
}
template
class monitor
{
mutable mutex m;
mutable T t;
public:
template
auto operator()(F f) const -> decltype(f(t))
{
return lock_guard(m),
f(t);
}
template friend
auto transaction(F f,const monitor& ...ms) ->
decltype(f(ms.t ...))
{
return lock(lvalue(unique_lock(ms.m,defer_lock))...),
f(ms.t ...);
}
};
int main()
{
monitor m[2];
transaction([](Account &x,Account &y)
{
x.money-=100;
y.money+=100;
},m[0],m[1]);
for(auto &&t : m)
cout << t([](Account &x){return x.money;}) << endl;
}
Output is:
900
1100