Lo scopo è di fare una fork. Il figlio incrementerà una variabile settata a 0 in memoria condivisa di 1 unita 50mila volte. Il padre invece la decrementerà.
Il risultato dovrebbe essere 0 poiche 0 + 50000 - 50000 = 0
A causa del timesharing, del processo a singolo thread e per la sovrascrittura dei registri del processore durante i cambi di contesto questo non accadrà.
Provare ad eseguire il primo codice piu volte e si vedranno continue variazioni di valore.
Nel secondo codice invece questo non avverrà.
Nessuna sincronizzazione
Sincronizzazione di Peterson
Il risultato dovrebbe essere 0 poiche 0 + 50000 - 50000 = 0
A causa del timesharing, del processo a singolo thread e per la sovrascrittura dei registri del processore durante i cambi di contesto questo non accadrà.
Provare ad eseguire il primo codice piu volte e si vedranno continue variazioni di valore.
Nel secondo codice invece questo non avverrà.
Nessuna sincronizzazione
PHP Code:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <st***.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
/***
* _ _
* (_) (_)
* __ ____ _ _ _____ ___ ___ ___ ___ _ __ ___
* \ \/ / _` | |/ _ \ \ / / |/ _ \ / __/ _ \| '_ ` _ \
* > < (_| | | (_) \ V /| | (_) | (_| (_) | | | | | |
* /_/\_\__, |_|\___/ \_/ |_|\___(_)___\___/|_| |_| |_|
* __/ |
* |___/
*
*
* Critical sections between parent and child - fork()
* Parent will decrement a variable of 1 unit 50000 times
* Child will increment the same variable of 1 unit 50000 times
*
* The result should be 0 but this isn't true.
* Without syncronization the result is unpredictable.
*
*/
#define SHMSZ 100
#define KEY 9999
int main ( void ) {
int shmid, status, shmdet, shmcontrol,err;
void * shmatt;
int * new_area;
/////////////creazione memoria condivisa
shmid = shmget ( KEY, SHMSZ, IPC_CREAT | IPC_EXCL | 660);
if (shmid == -1) { fprintf (stderr, "Impossibile creare segmento condiviso\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-1);}
//////////// attacco memoria condivisa a spazio processo
shmatt = shmat ( shmid, (void *)0 ,0);
if (shmatt == (void *) -1) { fprintf (stderr, "Impossibile modificare spazio indirizzi processo\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-2);}
new_area = (int *) shmatt;
///////////////////////////////////// begin fork /////////////////////////////////////////////////////////
*(new_area + 3)=0;
int i;
int pid;
pid = fork();
if ( pid == 0) {
//precritical section
////////////////////////////// begin critical section child process
//critical section
for (i=0;i<50000;i++){(*(new_area + 3))++;}
///////////////////////////// end critical section child process
// post critical section
shmdet = shmdt (shmatt);
if (shmatt == (void *)-1) { fprintf (stderr, "Impossibile detachare memoria condivisa\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-3);}
} else {
//precritical section
////////////////////////////// begin critical section parent process
//critical section
for (i=0;i<50000;i++){(*(new_area + 3))--;}
///////////////////////////// end critical section parent process
// post critical section
waitpid(-1,&status,0);
printf ( "Numero :%d\n",*(new_area + 3));
shmdet = shmdt (shmatt);
if (shmatt == (void *)-1) { fprintf (stderr, "Impossibile detachare memoria condivisa\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-4);}
shmcontrol = shmctl (shmid,IPC_RMID,NULL );
if (shmcontrol == -1) { fprintf (stderr, "Impossibile settare memoria condivisa per eliminazione\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-5);}
}
return 0;
}
PHP Code:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <st***.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
/***
* _ _
* (_) (_)
* __ ____ _ _ _____ ___ ___ ___ ___ _ __ ___
* \ \/ / _` | |/ _ \ \ / / |/ _ \ / __/ _ \| '_ ` _ \
* > < (_| | | (_) \ V /| | (_) | (_| (_) | | | | | |
* /_/\_\__, |_|\___/ \_/ |_|\___(_)___\___/|_| |_| |_|
* __/ |
* |___/
*
* Process syncronization between parent and child - fork()
* Parent will decrement a variable of 1 unit 50000 times
* Child will increment the same variable of 1 unit 50000 times
*
* The result is 0 using Peterson Algorithm to syncronize processes.
*/
#define SHMSZ 100
#define KEY 9999
int main ( void ) {
int shmid, status, shmdet, shmcontrol,err;
void * shmatt;
int * new_area;
/////////////creazione memoria condivisa
shmid = shmget ( KEY, SHMSZ, IPC_CREAT | IPC_EXCL | 660);
if (shmid == -1) { fprintf (stderr, "Impossibile creare segmento condiviso\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-1);}
//////////// attacco memoria condivisa a spazio processo
shmatt = shmat ( shmid, (void *)0 ,0);
if (shmatt == (void *) -1) { fprintf (stderr, "Impossibile modificare spazio indirizzi processo\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-2);}
new_area = (int *) shmatt;
int *flag; /// signal that process wants to go into critical section
flag = new_area;
int *turn;
turn = new_area + 2;
///////////////////////////////////// begin fork /////////////////////////////////////////////////////////
*(new_area + 3)=0;
int i;
int pid;
pid = fork();
if ( pid == 0) {
//precritical section
*(flag + 1)=1; // processo figlio vuole andare in sezione critica
*turn=0; // turno del processo padre
for (;(*turn) == 0 && *(flag)==1;) {sleep(1);} // attendo che il processo padre esca dalla sezione critica
////////////////////////////// begin critical section child process
//critical section
for (i=0;i<50000;i++){(*(new_area + 3))++;}
///////////////////////////// end critical section child process
// post critical section
*(flag + 1)=0;
shmdet = shmdt (shmatt);
if (shmatt == (void *)-1) { fprintf (stderr, "Impossibile detachare memoria condivisa\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-3);}
} else {
//precritical section
*flag=1; // processo padre vuole andare in sezione critica
*turn=1; // turno del processo figlio
for (;(*turn) == 1 && *(flag + 1)==1;) {sleep(1);} // attendo che il processo figlio esca dalla sezione critica
////////////////////////////// begin critical section parent process
//critical section
for (i=0;i<50000;i++){(*(new_area + 3))--;}
///////////////////////////// end critical section parent process
// post critical section
*(flag)=0;
waitpid(-1,&status,0);
printf ( "Numero :%d\n",*(new_area + 3));
shmdet = shmdt (shmatt);
if (shmatt == (void *)-1) { fprintf (stderr, "Impossibile detachare memoria condivisa\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-4);}
shmcontrol = shmctl (shmid,IPC_RMID,NULL );
if (shmcontrol == -1) { fprintf (stderr, "Impossibile settare memoria condivisa per eliminazione\n");
err= errno;
fprintf (stderr, "Errore %d\n",err);
exit (-5);}
}
return 0;
}