//------------------------------------------------------------------- // tryshm.cpp // // This program illustrates use of the four standard UNIX/Linux // shared-memory API functions, as prototyped in : // // int shmget( key_t key, int size, int shmflags ); // void *shmat( int shmid, char *shmaddr, int shmflags ); // void *shmdt( char *shmaddr ); // int shmctl( int shmid, int cmd, struct shmid_ds *buf ); // // Here a child-process acquires some information and shares it // with its parent-process by using a 'shared' memory-segment. // // programmer: ALLAN CRUSE // written on: 07 OCT 2004 //------------------------------------------------------------------- #include // for printf(), perror() #include // for strlen(), strtok() #include // for exit() #include // for fork() #include // for wait() #include // for shmget(), shmat(), shmdt(), shmctl() #define SHM_SIZE 40 // here we only need a small-sized buffer void child_task( int shm_handle ) { //-------------------------------------------------- // first, attach the parent's shared memory-segment //-------------------------------------------------- char *my_shm_address = (char*)shmat( shm_handle, 0, 0 ); if ( my_shm_address == (char*)-1 ) { perror( "shmat" ); exit(1); } //printf( "my_shm_address=%08X \n", my_shm_address ); //------------------------------------------------------ // next, do some work and share results with the parent //------------------------------------------------------ char prompt[] = "\nPlease type your name: "; write( STDOUT_FILENO, prompt, strlen( prompt ) ); read( STDIN_FILENO, my_shm_address, SHM_SIZE ); //---------------------------------------------------- // finally, detach the shared memory-segment and exit //---------------------------------------------------- printf( "(now the child is terminating)\n" ); shmdt( my_shm_address ); exit(0); } int main( void ) { //------------------------------------------- // begin by creating a shared memory-segment //------------------------------------------- int shm_handle; shm_handle = shmget( IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666 ); if ( shm_handle < 0 ) { perror( "shmget" ); exit(1); } //printf( "shm_handle=%d \n", shm_handle ); //------------------------------ // then start the child process //------------------------------ int status = 0, pid = fork(); if ( pid == 0 ) child_task( shm_handle ); //----------------------------------------------- // now attach the shared memory-segment and wait //----------------------------------------------- void *shm_address = shmat( shm_handle, NULL, 0 ); if ( shm_address == (void*)-1 ) perror( "shmat" ); //printf( "shm_address=%08X \n", shm_address ); wait( &status ); //-------------------------------------------------- // display the contents of the shared memory-memory //-------------------------------------------------- char *msg = (char*)shm_address; strtok( msg, "\n" ); // replaces '\n' with '\0' printf( "\nok, parent thinks you are \'%s\' \n", msg ); //------------------------------------------------ // then remove the shared memory-segment and exit //------------------------------------------------ printf( "(now the parent is terminating)\n" ); shmctl( shm_handle, IPC_RMID, 0 ); exit(0); }