/**
*
* Resuelve el problema del agua utilizando procesos y un monitor "Natural"
*
* Author: Sistemas Operativos (Francisco Arroyo)
*
* Version: 2023/Abr/23
*
* Problem description:
*
* You have just been hired by Mother Nature to help her out with the chemical reaction to form water,
* which she doesn't seem to be able to get right due to synchronization problems. The trick is to get two
* H atoms and one O atom react together at the same time. For our problem, each atom is represented by
* a thread. Each H atom thread invokes a procedure called H() when it is ready to react, and each O
* atom thread invokes a procedure called O() when it is ready
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include "Natural.h"
Natural natural;
Natural * naturalShared;
/**
* Código para el oxígeno
**/
int Oxigeno( int cual ) {
printf( "Se produjo un atomo de O\n" );
naturalShared->registraYEspera( AtomoOxigeno, cual );
exit( 0 );
}
/**
* Código para el hidrógeno
**/
int Hidrogeno( int cual ) {
printf( "Se produjo un atomo de H\n" );
naturalShared->registraYEspera( AtomoHidrogeno, cual );
exit( 0 );
}
/*
*
*/
int main( int argc, char ** argv ) {
long workers;
int worker, pid, memId;
workers = 100;
if ( argc > 1 ) {
workers = atol( argv[ 1 ] );
}
// Create shared memory area and copy object image to it
memId = shmget( IPC_PRIVATE, sizeof( struct Natural ), IPC_CREAT | 0600 );
if ( -1 == memId ) {
perror( "Fail to create shared memory segment" );
exit( 1 );
}
naturalShared = (Natural *) shmat( memId, NULL, 0 );
memcpy( (void *) naturalShared, (const void *) & natural, sizeof( Natural ) ); // Copy object to shared segment
// Create atoms
for ( worker = 0; worker < workers; worker++ ) {
pid = fork();
if ( ! pid ) {
srand( getpid() );
if ( 0 == random() % 2 ) {
Oxigeno( worker );
} else {
Hidrogeno( worker );
}
}
}
for ( worker = 0; worker < workers; worker++ ) {
int status;
pid_t pid = wait( &status );
}
shmdt( naturalShared );
shmctl( memId, IPC_RMID, NULL );
}