PDA

View Full Version : [c-linux]Problema sui semafori


andrea
28-11-2006, 17:35
Dovevo fare un semplicissimo programma in cui un processo padre doveva creare un semaforo e per 10 volte oggi 3 secondi doveva incrementarlo di 1, mentre il figlio doveva decrementare di uno il semaforo, e dirmi se l'operazione era andata a buon fine o meno.

Quindi mi aspetterei un output del tipo:

Incrementato semaforo
Figlio decrementa il semaforo
Figlio non puo' decrementare
Incrementato semaforo

Io ho provato a scrivere questo:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#define KEY (1000)

int main (void) {

int id,n=0;
pid_t pid;
union semun {
int val;
struct semid_ds *buf;
ushort * array;
} argument;

argument.val = 0;

id = semget(KEY, 1, 0666 | IPC_CREAT);

if(id < 0) {
fprintf(stderr, "Non ottengo il semaforo.\n");
exit(0);
}

if( semctl(id, 0, SETVAL, argument) < 0) {
fprintf( stderr, "Non setto il semaforo.\n");
}
else {
fprintf(stderr, "Semaforo %d inizializzato.\n", KEY);
}

pid = fork();
if ( pid < 0) {
printf ("Errore figlio non creato \n");
exit (-1);
}
if ( pid == 0) { /* Child */
printf ("Figlio %d creato con successo \n" ,getpid() );
int idsem; /* Identificatore del semaforo */
struct sembuf operations[1];
int retval; /* Valore di ritorno di semop() */

operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = 0;

idsem = semget(1000, 1, 0666);
if(id < 0) { /* Se il semaforo non esiste */
fprintf(stderr, "Non trovo il semaforo, esco.\n");
exit(0);
}

while(1) {

retval = semop(id, operations, 1);

if(retval == 0) {
printf("Processo figlio con id %d ha consumato una risorsa\n", getpid());
}
else {
printf("Processo figlio con id %d non ha ottenuto una risorsa\n", getpid());
}
sleep(1);
}
exit (0);
}
else {
struct sembuf operations[1];
int retval; /* Valore di ritorno di semop() */
operations[0].sem_num = 0;
operations[0].sem_op = 1;
operations[0].sem_flg = 0;

while(n != 10) {
sleep(3);
retval = semop(id, operations, 1);

if(retval == 0) {
printf("E' stato incrementato il semaforo.\n");
}
else {
printf("Non si e' riuscito ad incrementare il semaforo.\n");
perror("REASON");
}
n++;
}
kill(pid,SIGKILL);
}

return 0;
}


Il problema è che l'output e' di questo tipo:

E' stato incrementato il semaforo.
Processo figlio con id 2613 ha consumato una risorsa
E' stato incrementato il semaforo.
Processo figlio con id 2613 ha consumato una risorsa

E cosi via, secondo voi dove e' il problema?Puo' darsi che sia un "problema" di scheduler?

Grazie

andrea
29-11-2006, 22:28
nessuno qualche ideina?

ilsensine
30-11-2006, 09:32
Il comportamento è in linea con il codice che hai scritto.
Un decremento tramite semop blocca se il semaforo non è >0. Se vuoi un comportamento non bloccante, metti IPC_NOWAIT nel sem_flg del child.

andrea
30-11-2006, 10:28
E il bello che c'era anche scritto sul man, che pirla che sono :D
Ti ringrazio.