#include "bits/time.h" #include #include #include #include #include #include #include #define NUM_ACCOUNTS 5 #define NUM_TRANSFERS 20 // Monetary value in cents typedef long currency; void sprintf_currency(char *buffer, currency c) { if (c < 0) { c = -c; sprintf(buffer, "-"); buffer += sizeof(char); } sprintf(buffer, "$%ld.%.2ld", c / 100, c % 100); } void printf_currency(currency c) { if (c < 0) { c = -c; printf("-"); } printf("$%ld.%.2ld", c / 100, c % 100); } // Accounts (shared resource) typedef struct account { int account_id; currency balance; int transaction_count; pthread_mutex_t lock; // Account access mutex } account; // Global account array account accounts[NUM_ACCOUNTS]; // Threads pthread_t transfers[NUM_TRANSFERS]; typedef struct transfer_args { int transfer_id; account *from; account *to; currency amount; } transfer_args; void *transfer_thread(void *arg) { transfer_args *args = (transfer_args *)arg; int id = args->transfer_id; account *from = args->from; account *to = args->to; currency amount = args->amount; // Sort in increasing order account *acc1; account *acc2; if (from->account_id < to->account_id) { acc1 = from; acc2 = to; } else { acc1 = to; acc2 = from; } pthread_mutex_lock(&acc1->lock); printf("Thread %u: Locked account %u (1)\n", id, acc1->account_id); usleep(100); // Delay to account for other threads pthread_mutex_lock(&acc2->lock); printf("Thread %u: Locked account %u (2)\n", id, acc2->account_id); from->balance -= amount; to->balance += amount; from->transaction_count++; to->transaction_count++; printf("Thread %u: Unlocked account %u\n", id, acc1->account_id); printf("Thread %u: Unlocked account %u\n", id, acc2->account_id); pthread_mutex_unlock(&acc2->lock); pthread_mutex_unlock(&acc1->lock); return NULL; } int main() { // Initialize all accounts with 0 balance for (int i = 0; i < NUM_ACCOUNTS; i++) { accounts[i] = (account){.account_id = i, .balance = 0}; pthread_mutex_init(&accounts[i].lock, NULL); } // Initialize tellers transfer_args args[NUM_TRANSFERS]; for (int i = 0; i < NUM_TRANSFERS; i++) { args[i] = (transfer_args){.transfer_id = i, .from = &accounts[i % NUM_ACCOUNTS], .to = &accounts[(i + 1) % NUM_ACCOUNTS], .amount = 1000}; pthread_create(&transfers[i], NULL, transfer_thread, &args[i]); } // Wait for all threads to finish for (int i = 0; i < NUM_TRANSFERS; i++) { pthread_join(transfers[i], NULL); } // Print account balance totals for (int i = 0; i < NUM_ACCOUNTS; i++) { printf("Total in account %u: ", i); printf_currency(accounts[i].balance); printf("\n"); } return 0; }