problema semafori C
Inviato: giovedì 18 giugno 2015, 11:10
ciao a tutti, io ho questo codice
il mio problema è che quando incremento il semaforo nel case '-' , la wait dovrebbe andare a buon fine, l'if essere verificato e il programma finire, solo che il programa rimane bloccato nel case e non capisco il perchè
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#ifndef KEY
#define KEY 2 /*dimensione per il buffer di lettura/scrittura*/
#endif
int charToInt(char u){
int a=u-'0';
return a;
}
int numeroNodi(){
char buffer[50];
int nodesNumber;
memset(buffer,'\0',50); // Azzera la memoria in modo che non ci siano problemi quando si va a leggere del buffer
write(1,"inserisci i nodi da simulare: ",sizeof(char)*29);
read(0,buffer,50);
nodesNumber=atoi(buffer);
return nodesNumber;
}
void wait_sem(int id_sem, int numsem){
struct sembuf sem_buf;
sem_buf.sem_num=numsem;
sem_buf.sem_flg=0;
sem_buf.sem_op=-1;
semop(id_sem,&sem_buf,1); //semaforo rosso
}
void signal_sem(int id_sem,int numsem){
struct sembuf sem_buf;
sem_buf.sem_num=numsem;
sem_buf.sem_flg=0;
sem_buf.sem_op=1;
semop(id_sem,&sem_buf,1); //semaforo verde
}
union semun{
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
/* Linux specific part: */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
int main(int argc, char *argv[]){
int nodesNumber=numeroNodi();
int fd_in=-1,cont=0;
pid_t nodi[nodesNumber];
int a,i,j,nread[nodesNumber],maxRead=0;
pid_t pid;
ssize_t red;
key_t key_MEM;
key_t key_mem;
key_t key_sem;
key_t key_sem2;
int *mem;
int contatore=0,h;
int fine[nodesNumber];
int *memoria;
int *media;
char *c;
int curr_cont = 0;
char filename[9];
char operazioni[nodesNumber][256];
for(i=0;i<nodesNumber;i++){
for(j=0;j<256;j++){
operazioni[i][j]='-';
}
}
key_mem = ftok("elab2.c", 'a');
key_sem = ftok("elab2.c", 'b');
key_sem2 = ftok("elab2.c", 'c');
/////////////////////////////////////////// LETTURA DA FILE ////////////////////////////////////////////////////
for(i=0;i<nodesNumber;i++){
sprintf(filename,"file%d.txt",i+1);
if((fd_in=open(filename,O_RDONLY,0644))==-1)
write(2,"OPEN: -1",sizeof(char)*8);
nread[i]=read(fd_in,operazioni[i],256);
close(fd_in);
}
for(i=0;i<nodesNumber;i++){
if(nread[i]>=maxRead){
maxRead=nread[i];
}
}
maxRead++;
maxRead++;
for(j=0;j<nodesNumber;j++){
for(i=0;i<maxRead;i++){
if(operazioni[j][i]=='\n')
operazioni[j][i]=' ';
}
}
for(i = 0; i < maxRead; i++){
printf("FILE[%d]=%c \n",i,operazioni[1][i]);
}
/////////////////////////////////////////// MEMORIA CONDIVISA //////////////////////////////////////////////////
int size_mem=(((sizeof(int)*2)*2)*nodesNumber)+1;
int shmid=shmget(key_MEM,size_mem,IPC_CREAT | 0666);
if(shmid==-1){
write(2,"SHMGET: -1",sizeof(char)*10);
exit(1);
}
mem=(int*)(shmat(shmid,0,0));
if(mem==(void*)-1){
write(2,"SHMAT: -1",sizeof(char)*9);
exit(1);
}
memoria=mem;
media=mem;
/*for(i = 0; i < size_mem; i++){
printf("MEMORIA[%d]=%d \n",i,memoria[i]);
}*/
memoria[size_mem-1]=0;
printf("memoria[%i]=%i",size_mem-1,memoria[size_mem-1]);
char operazione1;
int z=0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////// SEMAFORI ////////////////////////////////////////////////////////////
int semNumber=nodesNumber+1;
struct sembuf oper;
int idSem=semget(key_MEM+1,semNumber,IPC_CREAT | 0666); // creo i semafori
if(idSem==-1){
write(2,"SEMGET: -1",sizeof(char)*10);
exit(1);
}
for(i=0;i<semNumber;i++){
if((semctl(idSem,i,SETVAL,0))==-1){
write(2,"SEMCTL: -1",sizeof(char)*10);
exit(1);
}
}
/*int idSemEnd=semget(key_mem+2,1,IPC_CREAT | 0666);
if(idSemEnd==-1){
write(2,"SEMGET altro: -1",sizeof(char)*10);
exit(1);
}
if((semctl(idSemEnd,0,SETVAL,0))==-1){
write(2,"SEMCTL: -1",sizeof(char)*10);
exit(1);
}*/
for(i=0;i<semNumber;i++){
printf("semaforo[%i]: %i\n",i,semctl(idSem,i,GETVAL));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////// CREAZIONE PROCESSI /////////////////////////////////////////////////
int flag=1;
char operazione;
for(i=1;i<=nodesNumber;i++){
j=0;
operazione=operazioni[i-1][j];
pid=fork();
if(pid==0)
{ // operazioni in comune per ogni processo
do{
switch(operazione){
case 'E':
printf("esecuzione processo %i\n sleep[%i]\n",i,charToInt(operazioni[i-1][j+2]));
sleep(charToInt(operazioni[i-1][j+2]));
j+=4;
operazione=operazioni[i-1][j];
break;
case 'R':
if(memoria[(i*4)-1]==0 && memoria[(i*4)-2]==0){
printf("ricezione processo %i fallita\n",i);
}
else{
memoria[(i*4)-1]=0;
memoria[(i*4)-2]=0;
printf("svuoto memoria ricezione [%i][%i]\n",memoria[(i*4)-1],memoria[(i*4)-2]);
}
j+=2;
operazione=operazioni[i-1][j];
break;
case 'S':
printf("scrivo nella zona di invio di %i [%i][%i]\n",i,charToInt(operazioni[i-1][j+2]),charToInt(operazioni[i-1][j+4]));
memoria[(i*4)-4]=charToInt(operazioni[i-1][j+2]);
memoria[(i*4)-3]=charToInt(operazioni[i-1][j+4]);
j+=6;
operazione=operazioni[i-1][j];
signal_sem(idSem,i-1);
break;
case ' ':
j+=1;
operazione=operazioni[i-1][j];
break;
case '-':
signal_sem(idSem,i-1);
flag=0;
printf("ultimo carattere\n");
memoria[size_mem-1]+=1;
printf("memoria[%i]=%i",size_mem-1,memoria[size_mem-1]);
//exit(0);
break;
default:
printf("operazione non conosciuta\n");
exit(1);
break;
}
}while(flag!=0);
//exit(0);
}
else
{
if(pid>0){
wait_sem(idSem,i-1);
printf("sono qui");
if(memoria[size_mem-1]==nodesNumber){
printf("istruzione finale ok\n");
exit(0);
return 0;
}
else{
/*if(memoria[((memoria[(i*4)-4])*4)-2]==0&&memoria[((memoria[(i*4)-4])*4)-1]==0){
memoria[((memoria[(i*4)-4])*4)-2]=i;
memoria[((memoria[(i*4)-4])*4)-1]=memoria[(i*4)-3];
memoria[(i*4)-4]=0;
memoria[(i*4)-3]=0;
printf("libero la zona di invio del processo %i [%i][%i]\n",i,memoria[(i*4)-4],memoria[(i*4)-3]);
}
else{
printf("invio di [%i][%i] del processo %i fallita\n",memoria[(i*4)-4],memoria[(i*4)-3],i);
}*/
}
}
else
{
fprintf(stderr, "Errore nel fork");
exit(1);
return 0;
}
}
}
exit(0);
}