#include #include #include #include #include struct account { pthread_mutex_t mutex; // protects balance int balance; }; struct thread_info { struct account *from; struct account *to; int n; int amount; }; static void * transfer_thread(void *_arg) { struct thread_info *info = _arg; for (int i = 0; i < info->n; i++) { pthread_mutex_t *l1 = &info->from->mutex; pthread_mutex_t *l2 = &info->to->mutex; if (l1 < l2) { pthread_mutex_lock(l1); pthread_mutex_lock(l2); } else { pthread_mutex_lock(l2); pthread_mutex_lock(l1); } if (info->from->balance >= info->amount) { info->from->balance -= info->amount; info->to->balance += info->amount; } if (l1 < l2) { pthread_mutex_unlock(l2); pthread_mutex_unlock(l1); } else { pthread_mutex_unlock(l1); pthread_mutex_unlock(l2); } } free(info); return 0; } static pthread_t start_transfer_thread(struct account *from, struct account *to, int n, int amount) { struct thread_info * info = malloc(sizeof(*info)); info->from = from; info->to = to; info->n = n; info->amount = amount; pthread_t t; pthread_create(&t, NULL, transfer_thread, info); return t; } int main() { struct account alice = { .balance = 1000000, .mutex = PTHREAD_MUTEX_INITIALIZER }; struct account bob = { .balance = 1000000, .mutex = PTHREAD_MUTEX_INITIALIZER }; printf("total balance before %d\n", alice.balance + bob.balance); pthread_t s = start_transfer_thread(&bob, &alice, 10000, 10); pthread_t t = start_transfer_thread(&alice, &bob, 10000, 10); pthread_join(t, (void **) NULL); pthread_join(s, (void **) NULL); printf("alice.balance %d bob.balance %d\n", alice.balance, bob.balance); printf("total balance after %d\n", alice.balance + bob.balance); return 0; }