Как синхронизировать доступ к двум объектам из разных потоков, если последовательность доступа может быть разной в разных потоках?

121
20 июня 2021, 06:10

Нужно написать функцию, которая переводит деньги с одного счета на другой.

struct Account {
    mutex mx;
    double amount;
};
void transfer(Account& from, Account& to, double value);

Эта функция может вызываться одновременно из разных потоков

Answer 1

В данном случае можно добиться строго одинаковой последовательности доступа путем сравнения указателей на объекты для определения порядка:

void transfer(Account& from, Account& to, double value)
{
     auto p_first{::std::addressof(from)};
     auto p_second{::std::addressof(to)};
     if(p_first == p_second)
     {
         return;
     }
     auto const address_first{reinterpret_cast<::std::uintptr_t>(p_first)};
     auto const address_second{reinterpret_cast<::std::uintptr_t>(p_second)};
     if(address_first > address_second)
     {
          ::std::swap(p_first, p_second);
     }
     ::std::lock_guard<::std::mutex> const lock_first{p_first->mutex};
     ::std::lock_guard<::std::mutex> const lock_second{p_second->mutex};
     from.amount -= value;
     to.amount += value;
}
Answer 2

В C++17 можно залочить 2 мьютекса так:

std::scoped_lock lck{from.mx, to.mx};
READ ALSO
Анонимные параметры в С++

Анонимные параметры в С++

Заметил, что если сделать анонимный параметр, компилятор не будет ругаться на это

101
Как освободить порт если он занят

Как освободить порт если он занят

У меня есть программа она занимает порт 4001 если ее не отключать и запустить еще одну программу она будет выдавать ошибку пока порт не закроетсяВопрос,...

91
Ошибка с inline

Ошибка с inline

Подскажите, пожалуйста, с чем может быть связана эта ошибка линковки:

76
constexpr функция вместо define &ldquo;функции&rdquo;

constexpr функция вместо define “функции”

ReSharper выдаёт предупреждение "function-like macro used; consider a constexpr template function", что значит: используйте constexpr функцию, вместо defineно при этом ReSharper не говорит...

111