Universidad de Costa Rica

Escuela de Ciencias de la Computación e Informática

CI-0122 Sistemas operativos

Ejemplos

CI0122 / Ejemplos



#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#include <unistd.h>
#include <stdlib.h>
#include <errno.h>


union semun {			// Needed to add an initial value to semaphore
      int              val;    /* Value for SETVAL */
      struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
      unsigned short  *array;  /* Array for GETALL, SETALL */
      struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
};



struct AreaCompartida {		// Defines the shared memory area representation
     int n;			// Tags included in this structure
     struct Etiqueta {		// Represents a tag
          char Nombre[ 50 ];	// Tag name
          int Veces;		// Tag count
     } Etiquetas[ 50 ];		// Tags array
};

typedef struct AreaCompartida AC;


int main() {

   AC * A;
   int shmid, semid;
   int size, st;
   union semun su;
   struct sembuf sb;
   
   semid = semget( 0xA12345, 1, IPC_CREAT | 0600 );	// Creates a semaphore
   su.val = 0;
   st = semctl( semid, 0, SETVAL, su );			// Initializes the semaphore to zero
   
   size = sizeof( AC );					// Calculates shared memory segment size
   shmid = shmget( 0xA12345, size, IPC_CREAT | 0600 );	// Creates the shared memory segment
   A = (AC *) shmat( shmid, NULL, 0 );			// Attachs this program to shared memory segment
   
   if ( ! fork() ) {		// Child process will fill the shared memory segment
      for ( int i = 0; i < 10; i++ ) {
         A -> n++;
	 sprintf( A -> Etiquetas[ i ].Nombre, "Palabra reservada %d", i );
	 A -> Etiquetas[ i ].Veces = i * 10;
      }
      sb.sem_num = 0;
      sb.sem_op  = 1;
      st = semop( semid, &sb, 1 );	// Wakes up the parent process

      exit( 0 );

   }

// Parent process continues here
   printf("This is parent process ... \n");
   sb.sem_num = 0;
   sb.sem_op = -1;
   st = semop( semid, &sb, 1 );	// Waits for the child

   for ( int j = 0; j < A -> n; j++ ) {		// Displays the shared memory segment contents
      printf( "La etiqueta: %s aparece %d veces \n", A -> Etiquetas[ j ].Nombre, A -> Etiquetas[ j ].Veces );
   }

// These calls are only executed by father process
   semctl( semid, 0, IPC_RMID );		// Destroys the semaphore
   
   shmdt( A );					// Detach variable A from shared memory
   shmctl( shmid, IPC_RMID, NULL );		// Removes the shared memory segment
   
   return 0;

}