From: skip@taygeta.oc.nps.navy.mil (Skip Carter)
Newsgroups: comp.lang.c++
Subject: Re: Objects in shared memory
Date: 26 Jan 93 20:43:33 GMT
Reply-To: skip@taygeta.oc.nps.navy.mil (Skip Carter)
Organization: Naval Postgraduate School, Monterey


	I tried to e-mail this but it bounced...

---- Cut Here and unpack ----
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#                                                                          
#                                                                          
#
#	Run the following text with /bin/sh to create:
#	  Classes.list
#	  Readme.sm
#	  Makefile
#	  sharmem.cpp
#	  sharmem.hpp
#	  persist.cpp
#	  smem.cpp
#	  smema.cpp
#	  smemb.cpp
#
if test -r s2_seq_.tmp
then echo "Must unpack archives in sequence!"
     next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
     exit 1; fi
echo "x - extracting Classes.list (Text)"
sed 's/^X//' << 'SHAR_EOF' > Classes.list &&
X
X
X	The following is a list of C++ classes that I have written and
X	am distributing by request to those that want them.
X
X
X	Derivs		Calculates the first derivative of a single
X			parameter function by using Richardson Extrapolation.
X			This class is a C++ translation of an Ada package
X			given in the May 1991 issue of Computer Language .
X
X	Kalman		A general purpose Kalman filter class for optimal
X			estimation of a dynamical system.
X
X
X	Model, Map, Ode, Runge
X
X			A family of classes that allows the treatement of
X			iterative maps and ordinary differential equations in
X			a unified manner.  The ordinary differential equations
X			are solved using the class Runge which is a C++ adaptation
X			of the code given in:
X			W.H. Press, B.P. Flannery, S.A. Teukolsky and W.T.
X			Vetterling, Numerical Recipes: The Art of Scientific
X			Computing, Cambridge Univ. Press, New York, 1986
X			These classes were the example classes described in
X			my recent Computer Language article:
X			The Evolution of a C++ programmer, Computer Language,
X			V. 9, No. 8, August 1992
X
X
X	MonteIntegrator, Quasi
X
X			 A Monte Carlo function integrator and its supporting
X			 random number generator.  The random number generator
X			 is a quasi-random (as opposed to a pseudo-random) number
X			 generator, this gives the integrator a 1/N convergence
X		         rate (as opposed to 1/Sqrt(N) ). Can integrate functions
X			 up to 5 dimensions (this limit is due to the quasi random
X			 number generator).
X
X
X
X	Shared		A Unix Shared Memory object base class.  When this
X			class is inherited by other classes then the derived
X			class becomes a shared memory object that can be
X			accessed by multiple processes.  These objects can be
X			persistant.
X
X	SimAnneal	A general purpose Simulated Annealing class, for
X			estimating optimum parameters of complicated functions
X			or systems.
X
X
X
X
X
X Everett (Skip) Carter             Phone:  408-646-3318 FAX: 408-646-2712
X Naval Postgraduate School         INTERNET: skip@taygeta.oc.nps.navy.mil
X Dept. of Oceanography, Code OC/CR  UUCP:     ...!uunet!taygeta!skip
X Monterey, CA. 93943               TELEMAIL: s.carter/omnet
X
X
X
X  (Note:  after 12 Dec 1992 the phone exchanges will change from 646 to 656)
SHAR_EOF
chmod 0644 Classes.list || echo "restore of Classes.list fails"
echo "x - extracting Readme.sm (Text)"
sed 's/^X//' << 'SHAR_EOF' > Readme.sm &&
X	Shared memory/persistant objects
X
X	The class Shared is a limited shared memory object that will also
X	allow persistant objects.
X
X	Each object is instantiated in a new shared memory segment which is
X	a system wide (limited) resource.  If the object is not deleted, it
X	will persist until the system is rebooted.  This can be exploited
X	purposely in order to get persistant objects (as in persist.cpp).
X
X	Objects that contain pointers or references to other objects or
X	variables that are not in shared memory will not work.  Also virtual
X	methods cannot be used.
X
X
X
X	The following code demonstrates of the use of shared memory:
X
X	smem		A single program that creates child processes
X			by forking.  The processes use shared memory
X			for refering to a common object
X
X
X	smema/smemb	Two independent programs that use shared memory
X			for a common object.  Start smema first, then
X			start smemb (which gets the handle info from a file
X			created by smemb).  When semaphores are NOT used,
X			start up smema in the background or from another window
X			and immediately start smemb (smema just waits for a while
X			and then assumes that there is valid data in the object).
X
X
X
X	persist	c	Creates an object in shared memory
X
X
X	persist r	Reads (and removes an object in shared memory that
X			was created with persist r).
X
X
X
X
X
X	See the comments in sharmem.hpp and in the demo code.
X
X
X
X
X Everett (Skip) Carter             Phone:  408-646-3318 FAX: 408-646-2712
X Naval Postgraduate School         INTERNET: skip@taygeta.oc.nps.navy.mil
X Dept. of Oceanography, Code OC/CR  UUCP:     ...!uunet!taygeta!skip
X Monterey, CA. 93943               TELEMAIL: s.carter/omnet
X
SHAR_EOF
chmod 0644 Readme.sm || echo "restore of Readme.sm fails"
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X# Makefile for misc C++ code
X#
XHOME = /usr/skip
XCLIB = $(HOME)/clib
XCPPLIB = $(HOME)/cpplib
XCLASSDIR = $(HOME)/classlib
X#
X#
X#
XCC = cc
XCFLAGS = -O -I$(HOME) -I.
XCPFLAGS = $(CFLAGS)
XCPP = CC
X#
X# The suffix for C++ code
XC++ = c++
X#
X#
XXFLAGS =  -I/usr/include/bsd -DXTFUNCPROTO
XLFLAGS = -lm
X#
X#
XXLIBS = -lXm -lXt -lX11 -lbsd
X#
X# use the appropriate version
XSEMAPHORE =
XSEMFLAG =
X#
X#SEMAPHORE = semaphore.o
X#SEMFLAG = -DUSE_SEMAPHORES
X#
X#
X# ===========================================================================
X#
X#
XEXPORT_SOURCES = derivs.hpp derivs.cpp sharmem.cpp sharmem.hpp map.cpp model.cpp \
X	ode.cpp runge.cpp map.hpp model.hpp ode.hpp runge.hpp quasi.cpp quasi.hpp \
X	standio.cpp standio.hpp getargs.h getargs.c stoi.c monteint.hpp \
X	monteint.cpp comment.cpp comment.hpp timestamp.hpp timestamp.cpp
X#
Xall: 	derivkit sharmemkit modelkit mckit comkit
X
X#
X# The test applications
X#
X#
Xmctest: mctest.$(C++) monteint.o quasi.o standio.o getargs.o stoi.o
X	$(CPP) $(CPFLAGS) -o mctest mctest.$(C++) monteint.o quasi.o standio.o getargs.o stoi.o -lm
X
Xmodriver: modriver.$(C++) model.o map.o ode.o runge.o
X	$(CPP) $(CPFLAGS) -o modriver modriver.$(C++) model.o map.o ode.o runge.o -lm
X
Xsmem: smem.$(C++) sharmem.o $(SEMAPHORE)
X	$(CPP) $(CPFLAGS) $(SEMFLAG) smem.$(C++) sharmem.o $(SEMAPHORE) -o smem
X
Xsmema: smema.$(C++) sharmem.o $(SEMAPHORE)
X	$(CPP) $(CPFLAGS) $(SEMFLAG) smema.$(C++) sharmem.o $(SEMAPHORE) -o smema
X
Xsmemb: smemb.$(C++) sharmem.o $(SEMAPHORE)
X	$(CPP) $(CPFLAGS) $(SEMFLAG) smemb.$(C++) sharmem.o $(SEMAPHORE) -o smemb
X
Xpersist: persist.$(C++) sharmem.o
X	$(CPP) $(CPFLAGS) persist.$(C++) sharmem.o -o persist
X
X#
X
Xsigtest:
X	$(CC) $(CFLAGS) -o sigtest sigtest.c
X#
X#
X# ============================================================================
X#
X#
Xclean:
X	-rm -f $(EXPORT_SOURCES)
X	-rm -f *.o *.bak *~
X
X#
X#
X#
X#	The source distribution kits
X#
X#
Xcomment.cpp: $(CLASSDIR)/comment.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/comment.c++ > comment.cpp
X
Xcomment.hpp: $(CLASSDIR)/comment.hpp
X	cp $(CLASSDIR)/comment.hpp comment.hpp
X
Xderivs.cpp: $(CLASSDIR)/derivs.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/derivs.c++ > derivs.cpp
X
Xderivs.hpp: $(CLASSDIR)/derivs.hpp
X	cp $(CLASSDIR)/derivs.hpp derivs.hpp
X
Xgetargs.c: $(CLIB)/getargs.c
X	cp $(CLIB)/getargs.c getargs.c
X
Xgetargs.h: $(CLIB)/getargs.h
X	cp $(CLIB)/getargs.h getargs.h
X
Xmap.hpp: $(CLASSDIR)/map.hpp
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/map.hpp > map.hpp
X
Xmap.cpp: $(CLASSDIR)/map.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/map.c++ > map.cpp
X
Xmodel.hpp: $(CLASSDIR)/model.hpp
X	cp $(CLASSDIR)/model.hpp model.hpp
X
Xmodel.cpp: $(CLASSDIR)/model.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/model.c++ > model.cpp
X
Xmonteint.hpp: $(CLASSDIR)/monteint.hpp
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/monteint.hpp > monteint.hpp
X
Xmonteint.cpp: $(CLASSDIR)/monteint.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/monteint.c++ > monteint.cpp
X
Xode.hpp: $(CLASSDIR)/ode.hpp
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/ode.hpp > ode.hpp
X
Xode.cpp: $(CLASSDIR)/ode.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/ode.c++ > ode.cpp
X
Xquasi.hpp: $(CLASSDIR)/quasi.hpp
X	cp $(CLASSDIR)/quasi.hpp  quasi.hpp
X
Xquasi.cpp: $(CLASSDIR)/quasi.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/quasi.c++ > quasi.cpp
X
Xrunge.hpp: $(CLASSDIR)/runge.hpp
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/runge.hpp > runge.hpp
X
Xrunge.cpp: $(CLASSDIR)/runge.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/runge.c++ > runge.cpp
X
X
Xsharmem.hpp: $(CLASSDIR)/sharmem.hpp
X	cp $(CLASSDIR)/sharmem.hpp sharmem.hpp
X
Xsharmem.cpp: $(CLASSDIR)/sharmem.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/sharmem.c++ > sharmem.cpp
X
Xstandio.hpp: $(CLASSDIR)/standio.hpp
X	cp $(CLASSDIR)/standio.hpp  standio.hpp
X
Xstandio.cpp: $(CLASSDIR)/standio.c++
X	cp $(CLASSDIR)/standio.c++ standio.cpp
X
Xstoi.c: $(CLIB)/stoi.c
X	cp $(CLIB)/stoi.c stoi.c
X
Xtimestamp.cpp: $(CLASSDIR)/timestamp.c++
X	sed s/"<classlib\/"/"<"/g < $(CLASSDIR)/timestamp.c++ > timestamp.cpp
X
Xtimestamp.hpp: $(CLASSDIR)/timestamp.hpp
X	cp $(CLASSDIR)/timestamp.hpp timestamp.hpp
X
XSHAR_SOURCE_CODE = Readme.sm Makefile sharmem.cpp sharmem.hpp persist.cpp smem.cpp \
X	      smema.cpp smemb.cpp
X
XMODEL_SOURCE_CODE = Makefile map.cpp map.hpp model.cpp model.hpp ode.cpp ode.hpp \
X		runge.cpp runge.hpp modriver.cpp
X
XMC_SOURCE_CODE = Readme.mc Makefile monteint.hpp monteint.cpp quasi.hpp quasi.cpp \
X	standio.cpp standio.hpp getargs.h getargs.c stoi.c mctest.cpp
X#
X#
Xderivkit: derivs.sh01
X
Xsharmemkit: sharmem.sh01
X
Xmodelkit: model.sh01
X
Xmckit: monte.sh01
X
Xcomkit: comkit.sh01
X
Xderivs.sh01: derivs.hpp derivs.cpp
X	shar2 -v -c -l64 -oderivs.sh Classes.list derivs.hpp derivs.cpp
X
Xsharmem.sh01: $(SHAR_SOURCE_CODE)
X	shar2 -v -c -l64 -osharmem.sh Classes.list $(SHAR_SOURCE_CODE)
X
Xmodel.sh01: $(MODEL_SOURCE_CODE)
X	shar2 -v -c -l64 -omodel.sh Classes.list $(MODEL_SOURCE_CODE)
X
Xmonte.sh01: $(MC_SOURCE_CODE)
X	shar2 -v -c -l64 -omonte.sh Classes.list $(MC_SOURCE_CODE)
X
Xcomkit.sh01: comment.hpp comment.cpp timestamp.hpp timestamp.cpp challenge1.cpp
X	shar2 -v -c -l64 -ocomkit.sh comment.hpp comment.cpp timestamp.hpp \
X			   	     timestamp.cpp challenge1.cpp
X
X#
X# Generics
X#
X#.asm.o:
X#	masm  $< /ML;
X# 
X.SUFFIXES :
X.SUFFIXES : .cpp .cxx .cpp .c .h .o
X
X.cpp.o:
X	$(CPP) $(CPFLAGS) -c $*.cpp
X
X.cxx.o:
X	$(CPP) $(CPFLAGS) -c $*.cxx
X
X.c++.o:
X	$(CPP) $(CPFLAGS) -c $*.c++
X
X.c.o:
X	$(CC) $(CFLAGS) -c $*.c
X
SHAR_EOF
chmod 0666 Makefile || echo "restore of Makefile fails"
echo "x - extracting sharmem.cpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > sharmem.cpp &&
X// sharmem.cpp		A Shared Memory Object base class implementation
X
Xstatic const char rcsid[] = "@(#)sharmem.c++	1.2 13:58:22 11/9/92   EFC";
X
X#include <iostream.h>
X
X#include <sharmem.hpp>
X
Xextern int errno;
X
Xvoid* Shared::operator new(size_t blocksize)
X{
X        Shared *rtn;
X	int shmsize, shmid;
X	
X
X	shmsize = blocksize;
X     	shmid = shmget( IPC_PRIVATE, shmsize, (IPC_CREAT | 0600) );
X     	if ( shmid == -1 )
X      	{
X	      	cerr << "Shared::new() shared memory get (shmget) failed (" <<
X			errno << ")\n",
X	      	exit(1);
X	}
X
X
X
X     	if ( (int)(rtn = (Shared *)shmat( shmid, 0, SHM_RND) ) == -1 )
X     	{
X            cerr << "Shared::new() (1) shared memory attach (shmat) error (" <<
X				errno << ")\n";
X	    exit(1);
X	}
X
X	rtn->shmid = shmid;
X	rtn->ref_count = 1;
X
X	return rtn;
X
X}
X
Xvoid* Shared::operator new(size_t, int master_is)
X{
X        Shared *rtn;
X
X     	if ( (int)(rtn = (Shared *)shmat( master_is, 0, SHM_RND) ) == -1 )
X     	{
X            cerr << "Shared::new() (2) shared memory attach (shmat) error (" <<
X				errno << ")\n";
X	    exit(1);
X	}
X
X	rtn->ref_count++;
X
X	return rtn;
X
X}
X
Xvoid Shared::operator delete(void *p)
X{
X	Shared* ps = (Shared *)p;
X
X	if ( ps->ref_count-- == 1 )
X	   	shmctl( ps->shmid, IPC_RMID, NULL);
X	else
X		shmdt( p );
X}
X
X
X
SHAR_EOF
chmod 0644 sharmem.cpp || echo "restore of sharmem.cpp fails"
echo "x - extracting sharmem.hpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > sharmem.hpp &&
X// sharmem.hpp		A Shared Memory Object base class definition
X
X// To use this class, an otherwise ordinary object can publicly inherit from
X// this class, one process, the "master", can treat the object in a normal way
X// all the other processes, the "clients", must declare the object as a pointer
X// and instantiate the object with the special version of new that requires the
X// shared memory block ID as a parameter
X
X
X// rcsid: @(#)sharmem.hpp	1.2 13:58:10 11/9/92 EFC
X
X#ifndef _SHAR_MEM_HPP_
X#define _SHAR_MEM_HPP_ 1.2
X
X#include <stdlib.h>
X
X#include <sys/types.h>
X#include <sys/ipc.h>
X#include <sys/shm.h>
X
Xclass Shared
X{
X	private:
X	  int shmid, ref_count;
X	protected:
X	  Shared() : id(shmid), ref_count(0) {}
X	public:
X	  const int& id;				// shared memory block id
X	  void *operator new(size_t blocksize);		// used by the master
X	  void *operator new(size_t,int master_is);	// used by clients
X	  void operator delete(void *);
X};
X
X#endif
SHAR_EOF
chmod 0444 sharmem.hpp || echo "restore of sharmem.hpp fails"
echo "x - extracting persist.cpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > persist.cpp &&
X// persist.cpp	Test using shared memory objects as persistant objects
X
X// usage	persist c		create the objects
X//		persist r		read (and remove) objects
X
X#define PROGRAM "persist"
X
X#include <fstream.h>
X#include <stdlib.h>
X#include <sysent.h>		// for fork(), may be elsewhere on other machines
X
X#include "sharmem.hpp"
X
X
Xextern int errno;
X
Xclass Cube : public Shared
X{
X	private:
X	  int x, y, z;
X	public:
X	  Cube() {}
X	  Cube(int a, int b, int c) : x(a), y(b), z(c) {}
X	 ~Cube() {}
X	  void size(int a, int b, int c) { x = a; y = b; z = c; }
X	  int volume() { return x * y * z; }
X};
X
X
Xvoid main(int argc, char **argv)
X{
X     int shmid, cubeid;
X     Cube *cube;
X     Cube *image;
X
X	if ( argc < 2 )
X	{
X	cerr << "Usage:\n\t" << PROGRAM << " c\t\tto create new objects\n";
X	cerr << '\t' << PROGRAM << " r\t\tto read and remove objects\n";
X	exit(1);
X	}
X
X     if ( *argv[1] == 'c' )
X     {
X
X     	image = new Cube;
X     	cube = new Cube;
X
X     	shmid = image->id;	// need this so that the shared one corresponds
X     	cubeid = cube->id;
X
X
X     	ofstream fout( "keys.dat" );
X     	if ( !fout )
X     	{
X		cerr << PROGRAM << " unable to open 'keys.dat' for output\n";
X		exit(1);
X     	}
X
X
X     	fout << shmid << '\n' << cubeid << '\n';
X
X	fout.close();
X
X	    image->size(2,3,4);
X
X	    cube->size(5,6,7);
X	}
X	else if ( *argv[1] == 'r' )
X	{
X
X     		ifstream fin( "keys.dat" );
X     		if ( !fin )
X     		{
X			cerr << PROGRAM << " unable to open 'keys.dat' for input\n";
X			exit(1);
X     		}
X
X     		fin >> shmid >> cubeid;
X
X
X		fin.close();
X
X      		cerr << "shmid: " << shmid << "\tcubeid: " << cubeid << endl;
X
X     		image = new(shmid) Cube;
X     		cube =  new(cubeid) Cube;
X
X	}
X	else
X	{
X
X	cerr << "Usage:\n\t" << PROGRAM << "c\t\tto create new objects\n";
X	cerr << '\t' << PROGRAM << "r\t\tto read and remove objects\n";
X	exit(1);
X
X	}
X
X
X	
X	cout << "The cube volume is: " << image->volume() << endl;
X
X	cout << "The 2nd cube volume is: " << cube->volume() << endl;
X
X
X	// NOTE: If you don't do this, you will eventually consume ALL
X	//       the systems shared memory resources
X
X	 if ( *argv[1] == 'r' )
X	 {
X	 	delete image;
X	 	delete cube;
X	 }
X
X}
X
X
X
X
X
SHAR_EOF
chmod 0666 persist.cpp || echo "restore of persist.cpp fails"
echo "x - extracting smem.cpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > smem.cpp &&
X// smem.cpp	Test using shared memory objects (and optionally semaphores)
X//		the synchronization WITHOUT semaphores will only work for simple
X//		programs (like this one), using SEMAPHORES is the preferred way
X//		to go.
X
X#define PROGRAM "smem"
X
X#include <iostream.h>
X#include <stdlib.h>
X#include <sysent.h>			// for fork()
X
X#include "sharmem.hpp"
X
X// #define USE_SEMAPHORES
X
X#ifdef USE_SEMAPHORES
X#include "semaphore.hpp"
X
X#define NSEM		1           /* set to the number of semaphores to use */
X
X#define SEM1		0
X#define SEM2		(NSEM-1)
X
X#endif
X
Xclass Cube : public Shared
X{
X	private:
X	  int x, y, z;
X	public:
X	  Cube() {}
X	  Cube(int a, int b, int c) : x(a), y(b), z(c) {}
X	 ~Cube() {}
X	  void size(int a, int b, int c) { x = a; y = b; z = c; }
X	  int volume() { return x * y * z; }
X};
X
X
XCube *image;
X
Xint semid = 1234;
X
Xvoid main()
X{
X     int child;
X     int shmid, cubeid;
X     Cube *cube;
X
X     image = new Cube;
X     cube =  new Cube;
X
X     shmid = image->id;		// need this so that the shared one corresponds
X     cubeid = cube->id;
X
X#ifdef USE_SEMAPHORES
X     semaphore sem(semid, NSEM, 0);
X#endif
X
X     if ( fork() == 0 )
X       {
X	    delete image;		// get rid of childs copy
X
X	    image = new(shmid) Cube;	// attach to shared copy of image
X
X#ifdef USE_SEMAPHORES
X      	semaphore sem(semid, NSEM, 0);
X#endif
X
X	    child = getpid();
X	    cout << "I am the child process: " << child;
X	    image->size(2,3,4);
X	    cout << "\tThe cube volume is: " << image->volume() << endl;
X
X	    delete image;
X
X	    sleep(1);
X#ifdef USE_SEMAPHORES
X	cerr << "(C1) Semaphore values: " << sem.value(SEM1) << '\n';
X	      sem[SEM1]++;
X	cerr << "(C1) Semaphore values: " << sem.value(SEM1) << '\n';
X#endif
X	      exit( 0 );
X	    }
X
X     if ( fork() == 0 )
X       {
X
X	    delete image;		// get rid of childs copy
X
X	    image = new(cubeid) Cube;	// attach to shared copy of cube
X#ifdef USE_SEMAPHORES
X     	    semaphore sem(semid,NSEM,0);
X#endif
X
X	    child = getpid();
X	    cout << "I am the child process: " << child;
X	    image->size(5,6,7);
X	    cout << "\tThe cube volume is: " << image->volume() << endl;
X
X
X	    delete image;
X
X#ifdef USE_SEMAPHORES
X	cerr << "(C2) Semaphore values: " << sem.value(SEM2) << '\n';
X	      sem[SEM2]++;
X	cerr << "(C2) Semaphore values: " << sem.value(SEM2) << '\n';
X#endif
X	      exit( 0 );
X	    }
X
X	// parent does this
X
X	// sleep( 3 );
X
X#ifdef USE_SEMAPHORES
X	cerr << "(P) Semaphore values: " << sem.value(0) << '\n';
X	cerr << "Decrementing the semaphore the first time\n";
X	sem[SEM1]--;
X	cerr << "Decrementing the semaphore the second time\n";
X	sem[SEM2]--;
X#else
X	int status;
X	child = wait(&status);
X	child = wait(&status);
X	cout << "The last child was: " << child << endl;
X#endif
X
X	cout << "The cube volume is: " << image->volume() << endl;
X
X	cout << "The 2nd cube volume is: " << cube->volume() << endl;
X
X
X	// NOTE: If you don't do this, you will eventually consume ALL
X	//       the systems shared memory resources
X
X	delete image;
X	delete cube;
X
X}
X
X
X
X
X
SHAR_EOF
chmod 0666 smem.cpp || echo "restore of smem.cpp fails"
echo "x - extracting smema.cpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > smema.cpp &&
X// smema.cpp	Test using shared memory objects (and optionally semaphores)
X//	two independent programs are used, this one creates the space and
X//	writes the keys to a file, the second one reads the keys and access the
X//	data
X
X#define PROGRAM "smemA"
X
X#include <fstream.h>
X#include <stdlib.h>
X#include <sysent.h>			// for fork()
X
X#include "sharmem.hpp"
X
X// #define USE_SEMAPHORES
X
X#ifdef USE_SEMAPHORES
X#include "semaphore.hpp"
X
X#define NSEM		1           /* set to the number of semaphores to use */
X
X#define SEM1		0
X#define SEM2		(NSEM-1)
X
X#endif
X
X
Xclass Cube : public Shared
X{
X	private:
X	  int x, y, z;
X	public:
X	  Cube() {}
X	  Cube(int a, int b, int c) : x(a), y(b), z(c) {}
X	 ~Cube() {}
X	  void size(int a, int b, int c) { x = a; y = b; z = c; }
X	  int volume() { return x * y * z; }
X};
X
X
Xint semid = 1234;
X
Xvoid main()
X{
X     int shmid, cubeid;
X     Cube *cube;
X     Cube *image;
X
X
X     image = new Cube;
X     cube = new Cube;
X
X     shmid = image->id;		// need this so that the shared one corresponds
X     cubeid = cube->id;
X
X#ifdef USE_SEMAPHORES
X     semaphore sem(semid, NSEM, 0);
X#endif
X
X     ofstream fout( "keys.dat" );
X     if ( !fout )
X     {
X	cerr << PROGRAM << " unable to open 'keys.dat' for output\n";
X	exit(1);
X     }
X
X
X     fout << shmid << '\n' << cubeid << '\n' << semid << '\n';
X
X	fout.close();
X
X
X	// sleep( 3 );
X
X#ifdef USE_SEMAPHORES
X	for (int i = 0; i < NSEM; i++)
X		cerr << "(P) Semaphore values: " << sem.value(i) << '\n';
X	cerr << "Decrementing the semaphore the first time\n";
X	sem[SEM1]--;
X	for (i = 0; i < NSEM; i++)
X		cerr << "(P) Semaphore values: " << sem.value(i) << '\n';
X	cerr << "Decrementing the semaphore the second time\n";
X	sem[SEM2]--;
X	for (i = 0; i < NSEM; i++)
X		cerr << "(P) Semaphore values: " << sem.value(i) << '\n';
X#else
X				// no semaphores so,
X	sleep( 5 );		// just wait a while and hope the obect is ready
X
X#endif
X
X	cout << "A:  The cube volume is: " << image->volume() << endl;
X
X	cout << "A:  The 2nd cube volume is: " << cube->volume() << endl;
X
X
X	// NOTE: If you don't do this, you will eventually consume ALL
X	//       the systems shared memory resources
X
X	 delete image;
X	 delete cube;
X
X}
X
X
X
X
X
SHAR_EOF
chmod 0666 smema.cpp || echo "restore of smema.cpp fails"
echo "x - extracting smemb.cpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > smemb.cpp &&
X// smemb.cpp	Test using shared memory objects (and optionally semaphores)
X//	two independent programs are used, this one
X//	reads the keys and access the data
X
X#define PROGRAM "smemB"
X
X
X#include <fstream.h>
X#include <stdlib.h>
X#include <sysent.h>			// for fork()
X
X#include "sharmem.hpp"
X
X// #define USE_SEMAPHORES
X
X#ifdef USE_SEMAPHORES
X#include "semaphore.hpp"
X
X#define NSEM		1           /* set to the number of semaphores to use */
X
X#define SEM1		0
X#define SEM2		(NSEM-1)
X
X#endif
X
Xclass Cube : public Shared
X{
X	private:
X	  int x, y, z;
X	public:
X	  Cube() {}
X	  Cube(int a, int b, int c) : x(a), y(b), z(c) {}
X	 ~Cube() {}
X	  void size(int a, int b, int c) { x = a; y = b; z = c; }
X	  int volume() { return x * y * z; }
X};
X
X
XCube *image;
X
X
Xvoid main()
X{
X     int child;
X     int shmid, cubeid, semid;
X     Cube *cube;
X
X     ifstream fin( "keys.dat" );
X     if ( !fin )
X     {
X	cerr << PROGRAM << " unable to open 'keys.dat' for input\n";
X	exit(1);
X     }
X
X     fin >> shmid >> cubeid >> semid;
X
X
X	fin.close();
X
X      cerr << "shmid: " << shmid << "\tcubeid: " << cubeid
X		 << "\tsemid: " << semid << endl;
X
X     image = new(shmid) Cube;
X     cube =  new(cubeid) Cube;
X
X
X#ifdef USE_SEMAPHORES
X     semaphore sem(semid, NSEM, 0);
X#endif
X
X
X	    child = getpid();
X	    cout << "I am the child process: " << child;
X	    image->size(2,3,4);
X	    cout << "\tThe cube volume is: " << image->volume() << endl;
X
X	    delete image;
X
X	    sleep(1);
X#ifdef USE_SEMAPHORES
X	cerr << "(C1) Semaphore values: " << sem.value(SEM1) << '\n';
X	      sem[SEM1]++;
X	cerr << "(C1) Semaphore values: " << sem.value(SEM1) << '\n';
X#endif
X
X
X	    child = getpid();
X	    cout << "B: I am the second process: " << child;
X	    cube->size(5,6,7);
X	    cout << "\tThe cube volume is: " << cube->volume() << endl;
X
X
X	    delete cube;
X
X#ifdef USE_SEMAPHORES
X	cerr << "(C2) Semaphore values: " << sem.value(SEM2) << '\n';
X	      sem[SEM2]++;
X	cerr << "(C2) Semaphore values: " << sem.value(SEM2) << '\n';
X#endif
X
X
X
X}
X
X
X
X
X
SHAR_EOF
chmod 0666 smemb.cpp || echo "restore of smemb.cpp fails"
exit 0

-- 
 Everett (Skip) Carter             Phone:  408-656-3318 FAX: 408-656-2712
 Naval Postgraduate School         INTERNET: skip@taygeta.oc.nps.navy.mil
 Dept. of Oceanography, Code OC/CR  UUCP:     ...!uunet!taygeta!skip
 Monterey, CA. 93943               TELEMAIL: s.carter/omnet

 (please note the new phone numbers)




-- 
 Everett (Skip) Carter        Phone:  408-656-3318 FAX: 408-656-2712
 Naval Postgraduate School    INTERNET: skip@taygeta.oc.nps.navy.mil
 Dept. of Oceanography, Code OC/CR  UUCP:     ...!uunet!taygeta!skip
 Monterey, CA. 93943          TELEMAIL: s.carter/omnet

 (please note the new phone numbers)