[C] Processi/pipe

di fuksa il
9 risposte
Salve, volevo chiedere se è possibile che tre processi, scrivendo su tre pipe diverse, comunichino con un quarto, il quale dovrà leggere tre messaggi diversi dalle tre pipe? E se no, c'è un altro modo per far avvenire tale comunicazione?

9 Risposte

  • La butto lì: il quarto programma crea tre figli/thread; ogni figlio/thread legge una delle pipe.
  • fuksa ha scritto:


    c'è un altro modo per far avvenire tale comunicazione?
    Copio e incollo con piccole modifiche da vecchio thread
    
    #include <stdio.h>
    #include <pthread.h>
    #include <semaphore.h>
    #include <time.h>
    
    #define MAX 10
    int A1[MAX];
    int A2[MAX];
    int A3[MAX];
    
    sem_t W1, W2, W3;
    
    void * writer_process1(void * arg){
        int i = 0;
        time_t start = time(0), s, t = 0;
        while(i < MAX){
            s = time(0) - start;
            if(t != s){
                t = s;               
                A1[i++] = i;   
                sem_post(&W1);          
            }
        }
    }
    
    void * writer_process2(void * arg){
        int i = 0;
        time_t start = time(0), s, t = 0;
        while(i < MAX){
            s = time(0) - start;
            if(t != s){
                t = s;               
                A2[i++] = i;   
                sem_post(&W2);  
            }
        }
    }
    
    void * writer_process3(void * arg){
        int i = 0;
        time_t start = time(0), s, t = 0;
        while(i < MAX){
            s = time(0) - start;
            if(t != s){
                t = s;               
                A3[i++] = i;   
                sem_post(&W3);            
            }
        }
    }
    
    void * reader_process(void * arg){
        for(int i = 0; i < MAX; i++){
            sem_wait(&W1);
            printf("Il processo 1 ha scritto A1[%d] = %d\n", i, A1[i]);
            sem_wait(&W2);
            printf("Il processo 2 ha scritto A2[%d] = %d\n", i, A2[i]);
            sem_wait(&W3);
            printf("Il processo 3 ha scritto A3[%d] = %d\n", i, A3[i]);        
        }
    }
    
    int main(){
        pthread_t wr1, wr2, wr3, rd;
    
        sem_init(&W1,0,0);
        sem_init(&W2,0,0);
        sem_init(&W3,0,0);
        
        pthread_create(&wr1, NULL, writer_process1, NULL);
        pthread_create(&wr2, NULL, writer_process2, NULL);
        pthread_create(&wr3, NULL, writer_process3, NULL);
        pthread_create(&rd,  NULL,  reader_process, NULL);    
    
        pthread_join(wr1, NULL);
        pthread_join(wr2, NULL);
        pthread_join(wr3, NULL);
        pthread_join(rd,  NULL);
        
        return 0;
    }
    
  • Allora, intanto grazie per le risposte. Io starei facendo un progetto in cui dato un padre e 4 figli: ad ogni secondo il padre legge una di un file di testo e invia a tre figli il valore letto in tre modi diversi per ciascuno, tramite rispettivamente socket, pipe e file condiviso. Dopodichè vorrei che ognuno dei tre figli inviasse su una pipe (magari tre pipe diverse) il valore letto al quarto figlio ma mi son accorto che ho problemi nella parte precedente a quella per cui ho aperto la discussione. Io avrei fatto così (tralascio la parte di definizione/inizializzazione variabili)
    		
    	int id=-1;
    		for(int i=0;i<4;i++){
    			pid[i]=fork();
    			if(pid[i]==0){
    				id=i;
    				break;
    			}
    		}			
    			
    
    		while(1){
    			sleep(1);
    			if(id==-1){
    				fgets(buffer, n,fg);
    			
    				close(fd[0]);
    				write(fd[1], buffer, n);
    				close(fd[1]);
    			
    				sfd=socket(AF_UNIX, SOCK_STREAM, 0);
    				bind(sfd, sSockAddrPtr, sizeof(sAddr));
    				listen(sfd, 5);
    				cfd=accept(sfd, cSockAddrPtr, &clen);
    				write(cfd, buffer, n);
    				close(cfd);
    			
    				out=fopen("sharedFile.txt","w");
    				fprintf(out, "%s", n);
    				fclose(out);
    			}
    			if(id==0){
    				close(fd[1]);
    				read(fd[0], message, n);
    				close(fd[0]);
    			}
    			if(id==1){
    				int result;
    				printf("%d - ",id);
    				cfd=socket(AF_UNIX, SOCK_STREAM, 0);
    			
    				do{
    					result=connect(cfd, sSockAddrPtr, sizeof(sAddr));
    				} while(result==-1);
    					read(cfd, message, n);
    					close(cfd);
    			}
    			if(id==2){
    				out=fopen("sharedFile.txt","r");
    				fgets(buffer2,n, out);
    				fclose(out);
    				}
    			}
    		}
    	
    Questo il pezzo con cui il padre dovrebbe inviare 3 valori che dovrebbero essere uguali ai 3 figli che poi lo elaboreranno ma prima vorrei capire se è giusto quello che ho fatto o cosa sto sbagliando più che altro nell'organizzazione dei processi
  • Non è più semplice usare pthread invece dei fork() per queste cose, visto che hai socket e file di mezzo?
  • Weierstrass ha scritto:


    Non è più semplice usare pthread invece dei fork() per queste cose, visto che hai socket e file di mezzo?
    Non li abbiamo fatti, quindi non li vuole.
  • Mi sono accorto stampando i risultati che la pipe nel ciclo mi legge solo alla prima iterazione, poi il messaggio letto rimane lo stesso per le iterazioni successive. A cosa è dovuto questo?
  • I cicli infiniti dovrebbero stare all'interno dei branch, non a monte, e le pipe non vanno chiuse
  • Weierstrass ha scritto:


    I cicli infiniti dovrebbero stare all'interno dei branch, non a monte, e le pipe non vanno chiuse
    Quindi dovrei avere il ciclo in ogni if? Non è la stessa cosa ma ridondante? E per le pipe dunque non si devono chiudere mai ne in lettura ne in scrittura? La sincronizzazione funziona lo stesso?
  • Continuare a controllare all'infinito quale processo sia prima di procedere non ha molto senso. La pipe la chiudi in lettura da una parte e scrittura dall'altra, ma se la chiudi in lettura e scrittura dallo stesso lato la comunicazione è finita
Devi accedere o registrarti per scrivere nel forum
9 risposte