Errore programmazione conccorrente

di il
8 risposte

Errore programmazione conccorrente

Non riesco a capire il motivo per cui con questo codice :
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <iostream>
#include "func.h"
#define dim 3

using namespace std;



int main(int argv, char *argc[]){
	
	key_t shmKey=IPC_PRIVATE;
	key_t semKey=IPC_PRIVATE;
	
	int shmID = shmget(shmKey,sizeof (int)*dim,IPC_CREAT|0664);
	cout<<"\nshmID = "<<shmID;
	
	int semID = semget(semKey,2,IPC_CREAT|0664);
	cout<<"\nsemID = "<<semID;
	
	//inizializzo i semafori
	semctl(semID,spazioDisp,SETVAL,1);
	semctl(semID,messDisp,SETVAL,0);
	//inizializzo la memoria condivisa
	int *ptrShm= (int *) shmat(shmID,0,0);
	
	//genero i processi
	
	int pid=fork();
	if(pid==0){
		cout<<"\nProcesso FIGLIO con pid : "<<getpid();
		}
	else cout<<"\nProcesso PADRE con pid :" <<getpid();
	
	
	
	cout<<"    processo "<<getpid()<<" terminato \n" ;
	}
ottengo questo output:

shmID = 12058684
semID = 2129955
Processo PADRE con pid :5243    processo 5243 terminato 
[poel@localhost 03- prod cons prova]$ semID = 2129955
Processo FIGLIO con pid : 5244    processo 5244 terminato 
in particolare non mi spiego la riga "[poel@localhost 03- prod cons prova]$ semID = 2129955" come se un processo ricominciasse da capo, mastampa solo semID e non shmID

sto veramente impazzendo....

8 Risposte

  • Re: Errore programmazione conccorrente

    L'output si confonde con la stampa della shell, prova a mettere una sleep() alla fine del processo padre in modo da ritardarne la fine
  • Re: Errore programmazione conccorrente

    Ho provato in questo modo:
    #include <iostream>
    #include <sys/types.h>
    #include <unistd.h>
    #include "func.h"
    using namespace std;
    
    int main(int argv, char *argc[]){
    	
    	cout<<"Processo iniziale con pid: "<<getpid();
    	int pid = fork();
    	if (pid==0){
    	cout<<"\nProcesso figlio con pid: "<<getpid();
    	sleep(1);
    	}
    	else
    	cout<<"\nProcesso PADRE con pid: "<<getpid();
    	sleep(1);
    	
    	sleep(2);
    	cout<<"Processo finito con pid: "<<getpid();
    } 
    l'output è stato questo :
    Processo iniziale con pid: 5660
    Processo iniziale con pid: 5660
    Processo PADRE con pid: 5660Processo finito con pid: 5660[poel@localhost Template]$ Processo figlio con pid: 5661Processo finito con pid: 5661
    
    
    
    
  • Re: Errore programmazione conccorrente

    Non è che potresti scrivere:
       int pid;
       cout<<"Processo iniziale con pid: "<<getpid();
       pid = fork();
    
  • Re: Errore programmazione conccorrente

    Vorrei riaprire questo thread poichè continuo a riscontrare quest'anomalia nei miei programmi:
    main:
    #include <iostream>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include "func.h"
    #include <wait.h>
    
    using namespace std;
    
    int main(){
    	
    	pid_t pid;
    	//creo sem e lo inizializzo
    	int idSem = semget(IPC_PRIVATE, 2, IPC_CREAT | 0664);
    	semctl(idSem, spazioDisp, SETVAL, 1);
    	semctl(idSem, messDisp, SETVAL, 0);
    	//DEBUG
    	cout << "\n [DEBUG] Semaforo creato con ID: " << idSem << endl;
    	cout << "\n [DEBUG] spazioDisp inizializzato a : " <<
    		semctl(idSem,spazioDisp, GETVAL);
    	cout << "\n [DEBUG] messDisp inizializzato a : " <<
    		semctl(idSem,messDisp, GETVAL);
    	
    	//creo shm 
    	int idShm = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0664);
    	int * mess;
    	mess = (int*) shmat(idShm, 0, 0);
    
    	//creo i processi
    	int nProd = 5;
    	int nCons = 5;
    	int nProcess = nProd + nCons;
    	for (int i = 0 ; i < nProcess ; i++){
    		pid = fork();
    		if (pid == 0){
    			if(i % 2 == 0){
    				produttore(idSem,mess);
    				sleep(3);
    				}else{
    				consumatore(idSem,mess);
    				sleep(1);
    				}
    			 _exit(0);
    			}
    	} 
    	
    
    	int status;
    	for (int i = 0 ; i < nProcess ; i++){
    		pid = wait(&status);	
    		if(pid==-1)
    			cout<<"\nERRORE\n"<<endl;
    		else
    		cout<<"\nFiglio n.ro "<<pid<<" è morto con status "<<status<<endl;
    	}
    
    
    	//elimino sem e shm
    	semctl(idSem, 0 , IPC_RMID);
    	shmctl(idShm, IPC_RMID, 0);
    	
    	
    cout<<endl<<endl;	
    }
    func.cpp
    #include "func.h"
    #include <iostream>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    using namespace std;
    
    void wait(int idSem, int semNum){
    	struct sembuf s;
    	s.sem_num = semNum;
    	s.sem_flg = 0;
    	s.sem_op = -1;
    	semop(idSem, &s, 1);
    }
    
    void signal(int idSem, int semNum){
    	struct sembuf s;
    	s.sem_num = semNum;
    	s.sem_flg = 0;
    	s.sem_op = 1;
    	semop(idSem, &s, 1);
    }
    
    
    void produttore(int idSem, int * mess){
    	wait(idSem, spazioDisp);
    	srand(time(NULL));
    	*mess = rand()% 10; //generare il seme con srand(time(NULL));
    	cout<<"\nProduttore ha generato :   "<<*mess<<endl;
    	sleep(1);
    	signal(idSem,messDisp);
    	
    }
    
    void consumatore(int idSem, int * mess){
    	wait(idSem,messDisp);
    	cout<<"\nConsumatore ha consumato :   "<<*mess<<endl;
    	signal(idSem,spazioDisp);
    }
    func.h
    #ifndef FUNC
    #define FUNC
    
    #define spazioDisp 0
    #define messDisp 1
    
    void wait(int, int);
    void signal(int, int);
    
    void produttore(int, int*);
    void consumatore(int, int*);
    
    
    #endif
    ho in output:
    [DEBUG] Semaforo creato con ID: 1671189
    
     [DEBUG] spazioDisp inizializzato a : 1
     [DEBUG] messDisp inizializzato a : 0
    Produttore ha generato :   7
     [DEBUG] messDisp inizializzato a : 0
    Consumatore ha consumato :   7
     [DEBUG] messDisp inizializzato a : 0
    Produttore ha generato :   6
     [DEBUG] messDisp inizializzato a : 0
     [DEBUG] messDisp inizializzato a : 0
    Figlio n.ro 8326 è morto con status 0
    Consumatore ha consumato :   6
     [DEBUG] messDisp inizializzato a : 0
    Produttore ha generato :   3
    
    Figlio n.ro 8328 è morto con status 0
     [DEBUG] messDisp inizializzato a : 0
    Consumatore ha consumato :   3
     [DEBUG] messDisp inizializzato a : 0
    Produttore ha generato :   7
    
    Figlio n.ro 8325 è morto con status 0
     [DEBUG] messDisp inizializzato a : 0
    Consumatore ha consumato :   7
    
    Figlio n.ro 8330 è morto con status 0
     [DEBUG] messDisp inizializzato a : 0
    Produttore ha generato :   4
    
    Figlio n.ro 8327 è morto con status 0
    
     [DEBUG] messDisp inizializzato a : 0
    Figlio n.ro 8334 è morto con status 0
    Consumatore ha consumato :   4
    
    Figlio n.ro 8329 è morto con status 0
    
    Figlio n.ro 8332 è morto con status 0
    
    Figlio n.ro 8333 è morto con status 0
    
    Figlio n.ro 8331 è morto con status 0
    
    
    le frasi di DEBUG dovrebbe stamparle soltanto all'inizio, invece si ripete sempre una
    
     [DEBUG] messDisp inizializzato a : 0
    in ogni processo
    continuo a non capirne il motivo
  • Re: Errore programmazione conccorrente

    Ti prego, cambia la dicitura "Figlio xxx è morto"; fa gelare il sangue nelle vene!
  • Re: Errore programmazione conccorrente

    AHAHaA non sono proprio un esperto di linux, ma se non sabaglio i processi solitamente vengono "uccisi".... quindi per me ... muoiono

    comunque sono ancora bloccato li
  • Re: Errore programmazione conccorrente

    I task vengono "killati(Killed)" uccisi ma nessuno "dies" muore. Al massimo diventano zombi o demoni ma son tutti carini che si uccidono a vicenda senza far morire nessuno.
  • Re: Errore programmazione conccorrente

    Se può aiutare ho fatto questo: ho commentato prima la riga:
    /*cout << "\n [DEBUG] messDisp inizializzato a : " <<
    		semctl(idSem,messDisp, GETVAL);*/
    e ho avuto lo stesso output, ma con la riga precedente che si ripeteva
     [DEBUG] Semaforo creato con ID: 262147
    
     [DEBUG] spazioDisp inizializzato a : 1
    Produttore ha generato :   3
     [DEBUG] spazioDisp inizializzato a : 1
    Consumatore ha consumato :   3
     [DEBUG] spazioDisp inizializzato a : 1
    Produttore ha generato :   2
     [DEBUG] spazioDisp inizializzato a : 1
    Consumatore ha consumato :   2
     [DEBUG] spazioDisp inizializzato a : 1
    Produttore ha generato :   0
     [DEBUG] spazioDisp inizializzato a : 1
    Consumatore ha consumato :   0
     [DEBUG] spazioDisp inizializzato a : 1
    Figlio n.ro 3224 è morto con status 0
    
    Figlio n.ro 3222 è morto con status 0
    
    Figlio n.ro 3223 è morto con status 0
    
    Figlio n.ro 3220 è morto con status 0
    
    Figlio n.ro 3221 è morto con status 0
    
    Figlio n.ro 3225 è morto con status 0
    
    
    quindi commentando anche :
    cout <</* "\n [DEBUG] spazioDisp inizializzato a : " <<
    		semctl(idSem,spazioDisp, GETVAL); */
    HO RISOLTO IL PROBLEMA, poichè mi sceive solo la prima linea di debug ottenendo l'autput desiderato:
    [DEBUG] Semaforo creato con ID: 294915
    
    Produttore ha generato :   7
    
    Consumatore ha consumato :   7
    
    Produttore ha generato :   2
    
    Consumatore ha consumato :   2
    
    Produttore ha generato :   0
    
    Consumatore ha consumato :   0
    
    Figlio n.ro 3238 è morto con status 0
    
    Figlio n.ro 3240 è morto con status 0
    
    Figlio n.ro 3239 è morto con status 0
    
    Figlio n.ro 3242 è morto con status 0
    
    Figlio n.ro 3241 è morto con status 0
    
    Figlio n.ro 3243 è morto con status 0
    Il problema è che continuo a non capire perchè quando facevo i due GETVAL uno dei due mi veniva stampato
Devi accedere o registrarti per scrivere nel forum
8 risposte