/* * Show an example of deadlock. * * Build with g++ -g account.cc -o account -lpthread * * On Linux, set LD_ASSUME_KERNEL to 2.4.1 first to use older * version of pthreads: * csh: setenv LD_ASSUME_KERNEL 2.4.1 * bash: export LD_ASSUME_KERNEL=2.4.1 * * Run with "account" * On deadlock, use ^Z to suspend. * Use "ps" to find process id. * Use gdb ./account to invoke gdb * Use "attach pid" to attach to process * "bt" will backtrace, "thread 1", "thread 2", etc. * will switch between threads. * * Godmar Back - gback@cs.vt.edu - Feb 2006 */ #include #include #include using namespace std; class account { pthread_mutex_t lock; int amount; const char *name; public: account(int amount, const char *name) : amount(amount), name(name) { pthread_mutex_init(&this->lock, NULL); } void transferTo(account *that, int amount) { pthread_mutex_lock(&this->lock); pthread_mutex_lock(&that->lock); cout << "Transfering $" << amount << " from " << this->name << " to " << that->name << endl; this->amount -= amount; that->amount += amount; pthread_mutex_unlock(&that->lock); pthread_mutex_unlock(&this->lock); } }; account acc1(10000, "acc1"); account acc2(10000, "acc2"); static void * transferthread(void *_) { for (int i = 0; i < 100000; i++) acc2.transferTo(&acc1, 20); } int main() { pthread_t t; pthread_create(&t, NULL, transferthread, NULL); for (int i = 0; i < 100000; i++) acc1.transferTo(&acc2, 20); pthread_join(t, NULL); }