problema semafori C

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
gian2991
Prode Principiante
Messaggi: 55
Iscrizione: sabato 4 aprile 2015, 0:24
Sesso: Maschile

problema semafori C

Messaggio da gian2991 »

ciao a tutti, io ho questo codice

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);
}
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è
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 4 ospiti