#include #include #include #include // for usleep #include // for time (srand) #define NUM_THREADS 4 #define NUM_TRANSACTIONS_PER_THREAD 5 int balance = 1000; // shared account balance pthread_mutex_t balance_lock; // mutex to protect balance typedef struct { int thread_id; } ThreadArgs; void *transaction_worker(void *arg) { ThreadArgs *targs = (ThreadArgs *)arg; int id = targs->thread_id; for (int i = 0; i < NUM_TRANSACTIONS_PER_THREAD; i++) { int amount = (rand() % 400) + 100; // 100–499 int action = rand() % 2; // 0 = withdraw, 1 = deposit // Lock before accessing/modifying shared balance pthread_mutex_lock(&balance_lock); if (action == 0) { // withdraw if (balance >= amount) { balance -= amount; printf("[Thread %d] Withdraw %d | New balance = %d\n", id, amount, balance); } else { printf("[Thread %d] Withdraw %d FAILED (Insufficient funds) | Balance = %d\n", id, amount, balance); } } else { // deposit balance += amount; printf("[Thread %d] Deposit %d | New balance = %d\n", id, amount, balance); } // Unlock after updating balance pthread_mutex_unlock(&balance_lock); // Sleep a bit to better interleave threads usleep(100000); // 0.1s } return NULL; } int main() { pthread_t threads[NUM_THREADS]; ThreadArgs args[NUM_THREADS]; // Initialize random seed srand((unsigned int)time(NULL)); // Initialize mutex if (pthread_mutex_init(&balance_lock, NULL) != 0) { perror("Mutex init failed"); return 1; } printf("Initial balance = %d\n\n", balance); // Create threads for (int i = 0; i < NUM_THREADS; i++) { args[i].thread_id = i; if (pthread_create(&threads[i], NULL, transaction_worker, &args[i]) != 0) { perror("pthread_create failed"); return 1; } } // Wait for all threads to finish for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } printf("\nFinal balance = %d\n", balance); // Destroy mutex pthread_mutex_destroy(&balance_lock); return 0; }