A simpler, safer approach to shared-state concurrent programming that doesn't compromise performance.
Use it for .
struct bank_account
{
int balance;
mutable std::mutex mutex;
};
void transfer(
bank_account& from,
bank_account& to,
int amount)
{
// avoid deadlock in case of self-transfer
if (&from == &to) return;
// lock both mutexes without deadlock
std::lock(from.mutex, to.mutex);
// make sure both already-locked mutexes are unlocked at end of scope
std::lock_guard lock1{from.mutex, std::adopt_lock};
std::lock_guard lock2{to.mutex, std::adopt_lock};
// finally, the business logic
from.balance -= amount;
to.balance += amount;
}
atomik
gets out of your way.
struct bank_account
{
int balance;
};
void transfer(
atomik::var<bank_account> from,
atomik::var<bank_account> to,
int amount)
{
atomik::do_atomically(
[=]() {
from.set({from.get().balance - amount});
to.set({to.get().balance + amount});
}
);
}
atomik
's atomic actions—a lockless alternative to lock-based critical sections—can make it a lot easier.atomik
API is both simple and well-documented. It makes easy things easy and hard things possible. If you run into any tricky cases you couldn't find in the docs, we'll fix them right away!