/* shm_server.cpp vers. 0.2 Test routine to change from c to c++ * FAC Sept 2010 Adapted from shm_server.c from: * Reference1: http://www.cs.cf.ac.uk/Dave/C/node27.html#SECTION002700000000000000000 * Reference 2: http://www.go4expert.com/forums/showthread.php?t=8461 * Compile: g++ -g -Wall shm_server.cpp -o shm_server */ #include #include #include #include #include //used for sleep() in Linux. #include //Linux sleep(secs); // extern unsigned int sleep (unsigned int __seconds); #include //Linux req. exit() #define SHMSZ 1024 //main() int main(int argc, char ** argv) { int shmid; key_t key; long int *shm, *s; //shared mem address long int iln, iln2; //used for loop index and also data transf. key = 91810; //number just refers to creation date, is a //name for the shared mem segment. printf("Creating the shared mem. segment ...\n"); if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) { perror("shmget"); exit(1); } // ? Not clear why NULL is used below) printf("Attaching the segment to our data space...\n"); /* see: "man shmat" : In SVID 3 (or perhaps earlier) the type of the shmaddr argument was changed from char * into const void *, and the returned type of shmat() from char * into void *. (Linux libc4 and libc5 have the char * prototypes; glibc2 has void *.) */ // http://www.go4expert.com/forums/showthread.php?t=8461 uses: //if ((shm = (int *)/*(char *)*/shmat(shmid, 0, 0)) == /*(char *)*/(int *) -1) if ((shm = (long int *)shmat(shmid, 0, 0)) == (long int *) -1) { /* None of the below work in c++ : (c++ is such an ass pain!) //if ((shm = (char *)shmat(shmid, 0, 0)) == (char *) -1) // if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) //shm = shmat(shmid, NULL, 0); //shm = shmat(shmid, (void *)0, 0); //if(shm == (char *) -1) // if(shm == (void *) -1) */ perror("shmat"); exit(1); } // shm should now point to the 1st shared mem loc. printf("Placing numbers into shared mem...\n"); iln = 0; // iln & shared mem are all "long int" s=shm; //leave shm same, and use s to index while(1) { *s = iln; printf("Placed %li in shared mem\n",iln); s=s+1; iln =iln +1; if(iln == 10)break; } /* * Finally, we wait until the other process * changes the first location of our sh memory * to '-1', indicating that it has read what we put there. */ printf("Waiting for mstun to write -1 in 1st mem loc....\n"); while(1) { //wait(); // do not use wait(). max'es out cpu. sleep(3); //sleep() does not max out cpu. See also usleep for microSecs iln = *shm; if (iln == -1) { // mstun has written a "-1" into first location. printf(" Detected a -1 in 1st mem space\n"); s = shm; s = s+1; iln2 = *s; printf(" 2nd loc is %li\n",iln2); if( iln == 0) { printf("Exiting...\n"); goto STOP; } // we are done with reading from client *shm = 0; //set to 0 lets client read and write printf("Server: Set 1st mem loc to 0\n"); printf("Waiting for mstun to write -1 in 1st mem loc....\n"); } } STOP: exit(0); //could place detach shared mem code here. If one does //not detach it it stays in Linux memory (but can be re-attached //when this process, or others are re-activated) //use "ipcs" command to check if active, or observe all sh mem locations. } //end of main()