friend void transfer(account& from,account& to, float amount) { std::lock_guard<std::mutex> lock_from(from.m); std::lock_guard<std::mutex> lock_to(to.m); from.balance -= amount; to.balance += amount; }
void transfer2(account& from,account& to, float amount) { std::lock(from.m,to.m); std::lock_guard<std::mutex> lock_from(from.m,std::adopt_lock); std::lock_guard<std::mutex> lock_to(to.m,std::adopt_lock); from.balance -= amount; to.balance += amount; }
void transfer(int client_id, Account& from, Account& to, int amount) { std::unique_lock<std::mutex> lock_from(from.getLock()); if (from.withdraw(amount)) { std::printf("%d: withdraw %d OK\n", client_id, amount); fflush(stdout); // to see withdraw messages std::unique_lock<std::mutex> lock_to(to.getLock()); to.deposit(amount); lock_to.unlock(); lock_from.unlock(); std::printf("%d: deposit %d OK\n", client_id, amount); } else { lock_from.unlock(); std::printf("%d: withdraw %d ERROR\n", client_id, amount); } }
void client(int client_id, Account& from, Account& to, int amount) { bool success = false; std::unique_lock<std::mutex> lock_from(from.getDeferLock()); std::unique_lock<std::mutex> lock_to(to.getDeferLock()); while(true) { if (lock_from.try_lock()) { if (lock_to.try_lock()) { transfer(client_id, from, to, amount); lock_to.unlock(); success = true; } lock_from.unlock(); } if (success) break; std::cout << "RETRY\n"; std::this_thread::sleep_for(std::chrono::milliseconds(rand()%100)); } }