diner.cc

来自「编译工具」· CC 代码 · 共 198 行

CC
198
字号
//				Package : threadtests// diner.cc			Created : 23/1/95 sll//// Copyright (C) AT&T Laboratories Cambridge 1994, 1995//// Description://     A solution to the infamous dining philosophers, implemented using//     the omnithread package.//     This program exercises the thread creation and destruction,//     mutexes and condition variables.////     Expected to see all the philosophers doing various things. None//     of them is absent.//       ///* $Log: diner.cc,v $ Revision 1.6.12.2  2006/01/11 18:18:58  dgrisby Support for Visual C++ 8. Revision 1.6.12.1  2004/10/17 20:14:31  dgrisby Updated support for OpenVMS. Many thanks to Bruce Visscher. Revision 1.6  1999/03/11 16:26:15  djr Updated copyright notice Revision 1.5  1997/12/09 20:21:58  sll Replaced macro __NT__ with __WIN32__// Revision 1.4  1997/06/03  10:59:49  tjr// new omnithread interface using exceptions and lock class for mutex & sem.//// Revision 1.3  1995/08/17  10:22:27  tjr// new thread stuff//// Revision 1.2  1995/03/13  16:26:44  sll// Added mutex around output to STDERR stream.//// Revision 1.1  1995/01/25  11:54:48  sll// Initial revision// */#include <omniORB4/CORBA_sysdep.h> // for HAVE_STD#ifdef HAVE_STD#  include <iostream>   using namespace std;#else#  include <iostream.h>#endif#include <stdlib.h>#include <omnithread.h>#ifdef __WIN32__static int last_rand = 0;#endifstatic omni_mutex rand_mutex;static int random_l(){    rand_mutex.lock();    int i = rand();#ifdef __WIN32__    last_rand = i;#endif    rand_mutex.unlock();    return i;}static omni_mutex print_mutex;#define PRINTMSG(x) do { print_mutex.lock(); x; print_mutex.unlock(); } while (0)#define N_DINERS 5	// n philosophers sharing n chopsticksstatic omni_mutex chopsticks[N_DINERS];// At most n philosophers are allowed into the room, others would// have to wait at the door. This restriction demonstrates the use// of condition variables.static omni_mutex     room_mutex;	// protects room_occupancy & philliesstatic omni_condition room_cond(&room_mutex);static int            room_occupancy = 0;static class philosopher* phillies[N_DINERS];             class philosopher : public omni_thread {    void run(void* arg) {	int id = *(int*)arg;	delete (int*)arg;#ifdef __WIN32__	rand_mutex.lock();	srand(last_rand);	rand_mutex.unlock();#endif	int l = id;	int r = l+1;	if (r == N_DINERS)	    r = 0;	if (l & 1)	{	    int t = l;	    l = r;	    r = t;	}	PRINTMSG(cerr << "Philosopher #" << id << " has entered the room." << endl);	int count = random_l() % 10 + 1;	while (count--)	{	    chopsticks[l].lock();	    chopsticks[r].lock();	    PRINTMSG(cerr << "Philosopher #" << id << " is eating spaghetti now." << endl);	    omni_thread::sleep(random_l()%2,random_l()%1000000000);	    chopsticks[l].unlock();	    chopsticks[r].unlock();	    PRINTMSG(cerr << "Philosopher #" << id << " is pondering about life." << endl);	    omni_thread::sleep(random_l()%2,random_l()%1000000000);	}	room_mutex.lock();	room_occupancy--;	phillies[id] = NULL;	room_mutex.unlock();	room_cond.signal();	PRINTMSG(cerr << "Philosopher #" << id << " has left the room (" << room_occupancy << " left)." << endl);    }    // the destructor of a class that inherits from omni_thread should never be    // public (otherwise the thread object can be destroyed while the    // underlying thread is still running).    ~philosopher() {}    void* make_arg(int i) { return (void*)new int(i); }public:    philosopher(int id) : omni_thread(make_arg(id)) {	start();    }};intmain(int argc, char ** argv){    int i;    room_mutex.lock();    for (i=0; i<N_DINERS; i++) {	phillies[i] = new philosopher(i);    }    room_occupancy = N_DINERS;    while (1) {	while (room_occupancy == N_DINERS) {	    PRINTMSG(cerr << "main thread about to block " << room_occupancy << endl);	    room_cond.wait();	}	// Hm.. someone has left the room.	room_mutex.unlock();	// Sleep for a while and then create a new philosopher        PRINTMSG(cerr << "main thread sleep" << endl);	omni_thread::sleep(1,200000000);        PRINTMSG(cerr << "main thread wake up" << endl);	room_mutex.lock();	for (i=0; i<N_DINERS; i++)	    if (phillies[i] == NULL)		break;	if (i == N_DINERS) {	    PRINTMSG(cerr << "Contrary to what I was told, no one has left the room!!!!\n");	    PRINTMSG(cerr << "I give up!!!" << endl);	    exit(1);	}	phillies[i] = new philosopher(i);	room_occupancy++;    }    return(0);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?