Programmazione concorrente | stampa doppia

di il
3 risposte

Programmazione concorrente | stampa doppia

Salve, sto provando a risolvere il problema del produttore consumatore con un buffer.
Il problema l'ho risolto, ma il programma presenta un'anomalia nel main:
in alcune porzioni se stampo una frase di debug, essa compare a video 2 volte inveche di una. Non capisco quale possa essere il motivo

Vi indico qual'è la stampa anomala con [DEBUG] :
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include "func.h"
using namespace std;



int main(int argv, char *argc[]){
	//creo il semaforo:
	key_t chiaveSem=IPC_PRIVATE;
	int idSem=semget(chiaveSem,2, IPC_CREAT|IPC_EXCL|0666);
	cout<<"\nidSem: " <<idSem << endl;
	//creo il buffer:
	key_t chiaveShm=IPC_PRIVATE;
	int idShm=shmget(chiaveShm, sizeof(int),IPC_CREAT|IPC_EXCL|0666);
	cout<<"\nidShm: " <<idShm << endl;
	
	//inizializzo i semafori
	semctl(idSem,messDisp,SETVAL,0);
	semctl(idSem,spazDisp,SETVAL,1);
	
	
	cout<<"[DEBUG] frase ripetuta ";
	
	
	
	//inizializzo il buffer
	int *msg;
	msg =(int * ) shmat(idShm,0,0);
	*msg=0;
	
	//genero i processi prod e consum
	pid_t PID;
	PID = fork();
	if(PID==0){
		for(int i=0;i<4;i++){
			produttore(idSem, msg);
			sleep(rand()%2);
			}
		return 0;
		}
		
	for(int i=0;i<4;i++){
		consumatore(idSem,msg);
		sleep(rand()%2);
	}

	
	
	
	
	//elimino il semaforo:
	if(semctl(idSem,2,IPC_RMID)==-1)
		cout<<"\nImpossibile eliminare il semaforo\n";
	else cout<<"\n\nSemaforo eliminato";
	//elimino il il buffer:
	if(shmctl(idShm,IPC_RMID,0)==-1)
		cout<<"\nImpossibile eliminare il buffer\n";
	else cout<<"\nBuffer eliminato\n";
} 

3 Risposte

  • Re: Programmazione concorrente | stampa doppia

    Manca il codice di conaumatore e produttore.


    In generale: se stampa doppio, non stai usando correttamente i semafori.

    Quale e' la frase di debug?
  • Re: Programmazione concorrente | stampa doppia

    Ho completato il programma e quel comportamento è sparito, anche se credo sia solo un caso . la frase di debug che si ripeteva è quel cout con la parola " [debug] ".

    in ogni caso sulle dispense che ho trovato su internet si parla di un ulteriore semaforo per l'accesso in mutua esclusione, però non mi è chiaro il suo significato... i due semafori per il buffer messDisp e spazDisp non garantiscono gli accessi mutuali alla risorsa?

    vi posto il codice completo:
    header:
    #ifndef head_
    #define head
    
    #include <iostream>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <sys/ipc.h>
    
    #define messDisp 0
    #define spazDisp 1
    
    using namespace std;
    
    
    void waitSem (int idSem, int semNum);
    void signalSem(int idSem, int semNum);
    void produttore(int idSem, int * data);  //gli passo un puntatore alla memoria condivisa (*msg nel main)
    void consumatore (int idSem, int * data);
    
    #endif
    func.cpp
    #include "func.h"
    
    
    void signalSem(int idSem, int semNum){
    	struct sembuf b;
    	b.sem_num = semNum;
    	b.sem_flg = 0;
    	b.sem_op = 1;
    	semop(idSem, & b, 1);
    }
    
    void waitSem (int idSem, int semNum){
    	struct sembuf b;
    	b.sem_num = semNum;
    	b.sem_flg = 0;
    	b.sem_op = -1;
    	semop(idSem, &b, 1);
    }
    
    
    void produttore(int idSem, int * msg){
    	cout<<"\nProduttore in esecuzione";
    	cout<<" - Inserire il messaggio : ";
    	int mess;
    	cin>>mess;
    	waitSem(idSem,spazDisp);
    	*msg=mess;
    	signalSem(idSem,messDisp);
    }
    
    void consumatore (int idSem, int* msg){
    	cout<<"\nConsumatore in esecuzione";
    	cout<<" - Valore letto : ";
    	waitSem(idSem,messDisp);
    	cout<<*msg;
    	signalSem(idSem,spazDisp);
    }

    il nuovo main
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <iostream>
    #include "func.h"
    using namespace std;
    
    
    
    int main(int argv, char *argc[]){
    	//creo il semaforo:
    	key_t chiaveSem=IPC_PRIVATE;
    	int idSem=semget(chiaveSem,2, IPC_CREAT|IPC_EXCL|0666);
    	cout<<"\nidSem: " <<idSem << endl;
    	//creo il buffer:
    	key_t chiaveShm=IPC_PRIVATE;
    	int idShm=shmget(chiaveShm, sizeof(int),IPC_CREAT|IPC_EXCL|0666);
    	cout<<"\nidShm: " <<idShm << endl;
    	
    	//inizializzo i semafori
    	semctl(idSem,messDisp,SETVAL,0);
    	semctl(idSem,spazDisp,SETVAL,1);
    	
    	
    	cout<<"[DEBUG] frase ripetuta ";
    	
    	
    	
    	//inizializzo il buffer
    	int *msg;
    	msg =(int * ) shmat(idShm,0,0);
    	*msg=0;
    	
    	//genero i processi prod e consum
    	pid_t PID;
    	int pidprova=getpid();///////////////////////////////////////////////////////////
    	cout<<endl<<"Pid padre (iniziale)"<<pidprova<<endl<<endl;////////////////////////
    	PID = fork();
    
    	if(PID==0){
    		for(int i=0;i<4;i++){
    			cout<<"\nSono il processo FIGLIO con pid: ";
    			pidprova=getpid();//////////////////////////////////////////////////////
    			cout<<pidprova<<"provo ad invocare il produttore"<<endl;
    			produttore(idSem, msg);
    			sleep(rand()%2);
    			}
    		return 0;
    		}
    		
    	for(int i=0;i<4;i++){
    		cout<<"\nSono il processo PADRE con pid: ";
    		pidprova=getpid();///////////////////////////////////////////////////////////
    		cout<<pidprova<<"provo ad invocare il consumatore"<<endl;
    		consumatore(idSem,msg);
    		sleep(rand()%2);
    	}
    
    	
    	
    	
    	
    	//elimino il semaforo:
    	if(semctl(idSem,2,IPC_RMID)==-1)
    		cout<<"\nImpossibile eliminare il semaforo\n";
    	else cout<<"\n\nSemaforo eliminato";
    	//elimino il il buffer:
    	if(shmctl(idShm,IPC_RMID,0)==-1)
    		cout<<"\nImpossibile eliminare il buffer\n";
    	else cout<<"\nBuffer eliminato\n";
    } 
  • Re: Programmazione concorrente | stampa doppia

    Ho completato il programma e quel comportamento è sparito, anche se credo sia solo un caso . la frase di debug che si ripeteva è quel cout con la parola " [debug] ".

    in ogni caso sulle dispense che ho trovato su internet si parla di un ulteriore semaforo per l'accesso in mutua esclusione, però non mi è chiaro il suo significato... i due semafori per il buffer messDisp e spazDisp non garantiscono gli accessi mutuali alla risorsa?

    vi posto il codice completo:
    header:
    #ifndef head_
    #define head
    
    #include <iostream>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <sys/ipc.h>
    
    #define messDisp 0
    #define spazDisp 1
    
    using namespace std;
    
    
    void waitSem (int idSem, int semNum);
    void signalSem(int idSem, int semNum);
    void produttore(int idSem, int * data);  //gli passo un puntatore alla memoria condivisa (*msg nel main)
    void consumatore (int idSem, int * data);
    
    #endif
    func.cpp
    #include "func.h"
    
    
    void signalSem(int idSem, int semNum){
    	struct sembuf b;
    	b.sem_num = semNum;
    	b.sem_flg = 0;
    	b.sem_op = 1;
    	semop(idSem, & b, 1);
    }
    
    void waitSem (int idSem, int semNum){
    	struct sembuf b;
    	b.sem_num = semNum;
    	b.sem_flg = 0;
    	b.sem_op = -1;
    	semop(idSem, &b, 1);
    }
    
    
    void produttore(int idSem, int * msg){
    	cout<<"\nProduttore in esecuzione";
    	cout<<" - Inserire il messaggio : ";
    	int mess;
    	cin>>mess;
    	waitSem(idSem,spazDisp);
    	*msg=mess;
    	signalSem(idSem,messDisp);
    }
    
    void consumatore (int idSem, int* msg){
    	cout<<"\nConsumatore in esecuzione";
    	cout<<" - Valore letto : ";
    	waitSem(idSem,messDisp);
    	cout<<*msg;
    	signalSem(idSem,spazDisp);
    }

    il nuovo main
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <iostream>
    #include "func.h"
    using namespace std;
    
    
    
    int main(int argv, char *argc[]){
    	//creo il semaforo:
    	key_t chiaveSem=IPC_PRIVATE;
    	int idSem=semget(chiaveSem,2, IPC_CREAT|IPC_EXCL|0666);
    	cout<<"\nidSem: " <<idSem << endl;
    	//creo il buffer:
    	key_t chiaveShm=IPC_PRIVATE;
    	int idShm=shmget(chiaveShm, sizeof(int),IPC_CREAT|IPC_EXCL|0666);
    	cout<<"\nidShm: " <<idShm << endl;
    	
    	//inizializzo i semafori
    	semctl(idSem,messDisp,SETVAL,0);
    	semctl(idSem,spazDisp,SETVAL,1);
    	
    	
    	cout<<"[DEBUG] frase ripetuta ";
    	
    	
    	
    	//inizializzo il buffer
    	int *msg;
    	msg =(int * ) shmat(idShm,0,0);
    	*msg=0;
    	
    	//genero i processi prod e consum
    	pid_t PID;
    	int pidprova=getpid();///////////////////////////////////////////////////////////
    	cout<<endl<<"Pid padre (iniziale)"<<pidprova<<endl<<endl;////////////////////////
    	PID = fork();
    
    	if(PID==0){
    		for(int i=0;i<4;i++){
    			cout<<"\nSono il processo FIGLIO con pid: ";
    			pidprova=getpid();//////////////////////////////////////////////////////
    			cout<<pidprova<<"provo ad invocare il produttore"<<endl;
    			produttore(idSem, msg);
    			sleep(rand()%2);
    			}
    		return 0;
    		}
    		
    	for(int i=0;i<4;i++){
    		cout<<"\nSono il processo PADRE con pid: ";
    		pidprova=getpid();///////////////////////////////////////////////////////////
    		cout<<pidprova<<"provo ad invocare il consumatore"<<endl;
    		consumatore(idSem,msg);
    		sleep(rand()%2);
    	}
    
    	
    	
    	
    	
    	//elimino il semaforo:
    	if(semctl(idSem,2,IPC_RMID)==-1)
    		cout<<"\nImpossibile eliminare il semaforo\n";
    	else cout<<"\n\nSemaforo eliminato";
    	//elimino il il buffer:
    	if(shmctl(idShm,IPC_RMID,0)==-1)
    		cout<<"\nImpossibile eliminare il buffer\n";
    	else cout<<"\nBuffer eliminato\n";
    } 
Devi accedere o registrarti per scrivere nel forum
3 risposte