#include #include #include #include #include #include #include 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; }