Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente bannato
    Registrato dal
    Apr 2009
    Messaggi
    30

    Programmazione pipe in unix & serie di fibonacci..

    Ciao a tutti, sto stuadiando Sistemi Operativi e sono ai miei primi esercizi di creazione di processi sotto un sistema Unix...

    devo far condividere unsegmento di memoria tra 2 processi tramite una pipe; il processo genitore deve creare la successione di fibonacci e il processo figlio deve stamparla..

    ho impostato questo codice ma sicuramente ho bisogno di un aiuto per correggerlo;

    codice:
    #include<stdio.h>
    #include<unistd.h>
    #include<sys/shm.h>
    #include<sys/stat.h>
    
    #define BUFFER_SIZE 30
    
    int fibo(int fb);
    int i, x, y, buffer, fd[2];
    main(int argc, char argv[])
    {
     int segment_id, *shared_memory;
     const int size = 5000;
     if(argc<2)
     {
      printf("usage \"fibonacci\"<int value>\n");
      return 0;
     }
    
     i = atoi(argv[1]);
    
     pid_t pr;
    
     pipe(fd);   
     pr = fork();
    
     if(pr<0)
      fprintf(stderr, "Error generating process\n");
     else if(pr>0)
     {
      close(fd[0]); 
      segment_id = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
    
      write(fd[1], buffer, BUFFER_SIZE);
      shared_memory = (int *)shmat(fd, NULL, 0);
      for(x=0;x<=i;x++)
      {
       buffer = fibo(x);
       sprintf(shared_memory, buffer);
      }
    
      close(fd[1]);
     }
     else
     {
      close(fd[1]);
      read(fd[0], buffer, BUFFER_SIZE);
      for(y=0;x<=i;y++)
      {
       printf("%d\n", buffer);
      }
      close(fd[0]);
      shmdt(shared_memory);
     }
     shmctl(segment_id, IPC_RMID, NULL);
    }
    
    fibo(int fb)
    { 
     if(fb==0 || fb ==1)
      fb = 1;
     else
     fb = fibo(fb-1) + fibo(fb-2);
     return fb;
    }
    Qualcuno mi puo aiutare?? Grazie mille!!

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326

    Re: Programmazione pipe in unix & serie di fibonacci..

    Originariamente inviato da chaka
    devo far condividere unsegmento di memoria tra 2 processi tramite una pipe;
    Non capisco il termine "tramite"... una pipe non serve a "far convidivere un segmento di memoria tra 2 processi", ma semplicemente a metterli in comunicazione... è un meccanismo di IPC, non c'entra con la memoria condivisa.

    Originariamente inviato da chaka
    il processo genitore deve creare la successione di fibonacci e il processo figlio deve stamparla..
    Se questo è quello che devi fare, non c'è bisogno di ricorrere alla memoria condivisa. Il processo padre deve aprire entrambe le estremità della pipe (lettura e scrittura) richiamando appunto pipe(), a quel punto crea il processo figlio che eredita entrambi i descrittori associati alle due estremità della pipe. Fatto questo, poiché il processo figlio deve leggerci, chiude l'estremita in scrittura, legge i dati (in questo caso i numeri della successione di Fibonacci) e li stampa. Il processo padre, invece, chiude l'estremità della pipe in lettura (perché lui invece deve scriverci) e appunto scrive nella pipe i numeri della successione di Fibonacci, che saranno letti e stampati dal processo figlio.

    ho impostato questo codice ma sicuramente ho bisogno di un aiuto per correggerlo;
    Al di là dei concetti relativi alla programmazione di sistema Unix, il codice presenta diversi errori (o per meglio dire warnings, ma non trascurabili) dovuti ad uno scorretto uso delle funzioni...

    Compilando con -Wall -pedantic ottengo:

    codice:
    fibonacci.c:11: warning: return type defaults to 'int'
    fibonacci.c:11: warning: second argument of 'main' should be 'char **'
    fibonacci.c: In function 'main':
    fibonacci.c:20: warning: implicit declaration of function 'atoi'
    fibonacci.c:22: warning: ISO C90 forbids mixed declarations and code
    fibonacci.c:34: warning: passing argument 2 of 'write' makes pointer from integer without a cast
    fibonacci.c:35: warning: passing argument 1 of 'shmat' makes integer from pointer without a cast
    fibonacci.c:39: warning: passing argument 1 of 'sprintf' from incompatible pointer type
    fibonacci.c:39: warning: passing argument 2 of 'sprintf' makes pointer from integer without a cast
    fibonacci.c:47: warning: passing argument 2 of 'read' makes pointer from integer without a cast
    fibonacci.c:56: warning: control reaches end of non-void function
    fibonacci.c: At top level:
    fibonacci.c:59: warning: return type defaults to 'int'
    il mio consiglio e di correggere questi warnings prima di procedere... si tratta principalmente di rivedere come hai dichiarato le variabili che passi alle funzioni (tanto per dirne una, "buffer" nel tuo caso deve essere un array di 30 elementi se vuoi passarlo alla write... o comunque in generale un puntatore).

    Se hai problemi, chiedi pure
    every day above ground is a good one

  3. #3
    Utente bannato
    Registrato dal
    Feb 2004
    Messaggi
    2,803
    codice:
    #include<stdio.h>
    #include<stdlib.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include<unistd.h>
    #include<string.h>
           #include <sys/types.h>
           #include <sys/stat.h>
           #include <fcntl.h>
    
    
    int fibo(int fb)
    {
    if(fb==0 || fb ==1)
    fb = 1;
    else
    fb = fibo(fb-1) + fibo(fb-2);
    return fb;
    } 
    
    int main (){
    
    int fd[2];
    int pid,n,num=0;
    pipe(fd);
    pid=fork();
    
    if(pid==0){
    close(fd[1]);
    int buf;
    while((n=read(fd[0],&buf,128))>0){
    
    printf("%d\n",buf);
    }
    } else {
    close(fd[0]);
    int id = shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT | S_IRWXU);
    int*addr = (int*)shmat(id,0,0);
    while(num<10){
    num++;
    n=fibo(num);
    printf("%d\n",n);
    memcpy(addr,&n,sizeof(int));
    write(fd[1],addr,sizeof(int));
    }
    }
    }
    ho utilizzato il tuo problema come esercitazione, posto la mia soluzione
    in effetti come dice yuyevon è un pò inutile usare la memoria condivisa in questo caso.
    io cmq ho proceduto così:
    il padre: calcola l'ennesimo numeri di fibo, lo scrive nella mem condivisa, e poi write che prende dalla mem condivisa e scrive nella pipe
    figlio: legge dalla pipe e stampa

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    in effetti come dice yuyevon è un pò inutile usare la memoria condivisa in questo caso.
    Ma non riesco a capire... anche tu ricorri alla memoria condivisa... ma è per caso proprio un esercizio la cui traccia lo richiede? Cioè è davvero un abuso XD

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <errno.h>
    
    int fibo(int n)
    {
    	int i, F1 = 1, F2 = 0, ris;
    
    	if ( n < 2 )
    		return n;
    
    	for ( i = 2 ; i <= n ; i++ ) {
    		ris = F1 + F2;
    
    		F2 = F1;
    		F1 = ris;
    	}
    
    	return ris;
    }
    
    int main(void)
    {
    	int fd[2], n, num = 0;
    	pid_t pid;
    
    	pipe(fd);
    
    	if ( ( pid = fork() ) < 0 ) {
    		fprintf(stderr, "Errore nella creazione del processo: %s\n", strerror(errno));
    		exit(errno);
    	}
    
    	if (pid == 0) {
    
    		close(fd[1]);
    
    		while ( read(fd[0], &n, sizeof(int)) )
    			printf("%d\n", n);
    
    		close(fd[0]);
    		exit(0);
    	}
    	else {
    
    		close(fd[0]);
    
    		while (num < 10) {
    			num++;
    			n = fibo(num);
    			write(fd[1], &n, sizeof(int));
    		}
    
    		close(fd[1]);
    	}
    
    	exit(0);
    }
    Comunque amici i processi vanno terminati... a meno che non amiamo programmarci delle fork bomb ;D

    Inoltre sconsiglio vivamente l'uso dell'algoritmo di Fibonacci ricorsivo semplice perché

    http://forum.html.it/forum/showthrea...ight=fibonacci
    every day above ground is a good one

  5. #5
    Utente bannato
    Registrato dal
    Feb 2004
    Messaggi
    2,803
    codice:
    #include<stdio.h>
    #include<stdlib.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include<unistd.h>
    #include<string.h>
           #include <sys/types.h>
           #include <sys/stat.h>
           #include <fcntl.h>
           #include <sys/sem.h>
    
    
    int fibo(int fb)
    {
    if(fb==0 || fb ==1)
    fb = 1;
    else
    fb = fibo(fb-1) + fibo(fb-2);
    return fb;
    } 
    
    int main (){
    
    int fd[2];
    int pid,n,num=0;
    int semid=(IPC_PRIVATE,1,IPC_CREAT | S_IRWXU);
    semctl(semid,1,SETVAL);
    struct sembuf sem;
    sem.sem_num=0;
    sem.sem_flg=0;
    pipe(fd);
    pid=fork();
    
    if(pid==0){
    close(fd[1]);
    int buf;
    while((n=read(fd[0],&buf,128))>0){
    sem.sem_op=-1;
    semop(semid,&sem,1);
    printf("%d\n",buf);
    sem.sem_op=1;
    semop(semid,&sem,1);
    sem.sem_op=0;
    semop(semid,&sem,1);
    }
    } else {
    close(fd[0]);
    int id = shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT | S_IRWXU);
    int*addr = (int*)shmat(id,0,0);
    while(num<10){
    sem.sem_op=-1;
    semop(semid,&sem,1);
    num++;
    n=fibo(num);
    printf("%d\n",n);
    memcpy(addr,&n,sizeof(int));
    write(fd[1],addr,sizeof(int));
    sem.sem_op=1;
    semop(semid,&sem,1);
    sem.sem_op=0;
    semop(semid,&sem,1);
    }
    shmdt(addr);
    }
    }


    posto anche la versione con i semafori perchè ho notato che capita che il padre faccia tranquillamente più iterazioni mentre il figlio legge

    @yu: l'ho visto come esercizio quindi non ho chiesto il perchè della shmem

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    @yu: l'ho visto come esercizio quindi non ho chiesto il perchè della shmem
    E in effetti l'uso dei semafori sarebbe l'unica cosa che potrebbe almeno in parte giustificare il ricorso alla memoria condivisa. Dico in parte perché ci sono pur sempre i semafori POSIX basati su file system con cui si potrebbero sincronizzare processi ancora senza memoria condivisa, appunto perché questi semafori hanno persistenza su file system finché non vengono esplicitamente chiusi e cancellati (se lo si vuole fare).
    every day above ground is a good one

  7. #7
    Utente bannato
    Registrato dal
    Apr 2009
    Messaggi
    30

    semafori

    GRAZIE mille a tutti per le risposte ragazzi, si lo ammetto il mi osorgente aveva qualche errore ma avevo anche un po il fumo alle orecchie, e ammetto che i ai semafori non ci sono ancora arrivato anche se ho visto l'argomento sfogliando pagine piu in la di dove sono arrivato..

    Ora non ho tempo di vedere con attenzione i vostri sorgenti, bensi domani mattina...

    Prometto una risposta appena posso!!

    Ciao e grazie ancora!! Gia lo so che mi avete dato una lezione anticipata e che sarebbe andata cosi. visto che sono nuovo con i processi!

  8. #8
    Utente bannato
    Registrato dal
    Apr 2009
    Messaggi
    30

    Re: Re: Programmazione pipe in unix & serie di fibonacci..

    Originariamente inviato da YuYevon
    Non capisco il termine "tramite"... una pipe non serve a "far convidivere un segmento di memoria tra 2 processi", ma semplicemente a metterli in comunicazione... è un meccanismo di IPC, non c'entra con la memoria condivisa.



    Se questo è quello che devi fare, non c'è bisogno di ricorrere alla memoria condivisa. Il processo padre deve aprire entrambe le estremità della pipe (lettura e scrittura) richiamando appunto pipe(), a quel punto crea il processo figlio che eredita entrambi i descrittori associati alle due estremità della pipe. Fatto questo, poiché il processo figlio deve leggerci, chiude l'estremita in scrittura, legge i dati (in questo caso i numeri della successione di Fibonacci) e li stampa. Il processo padre, invece, chiude l'estremità della pipe in lettura (perché lui invece deve scriverci) e appunto scrive nella pipe i numeri della successione di Fibonacci, che saranno letti e stampati dal processo figlio.


    il mio consiglio e di correggere questi warnings prima di procedere... si tratta principalmente di rivedere come hai dichiarato le variabili che passi alle funzioni (tanto per dirne una, "buffer" nel tuo caso deve essere un array di 30 elementi se vuoi passarlo alla write... o comunque in generale un puntatore).

    Se hai problemi, chiedi pure
    Ciao YuYevon grazie per la tua spiegazione, si effettivamente mi ero confuso nel fatto di "far condividere la memoria tramite una pipe" , anche se gia lo sapevo, effettivamente la mia tecnica nell'esercizio era un po sbagliata.. Ti ringrazio moltissimo, comunque si, l'esercizio richiedeva una condivisione di memoria, magari chissa non era il caso di utilizzare la api POSIX pero va bene lo stesso, sono contento di tutti i consigli. Ancora grazie

  9. #9
    Utente bannato
    Registrato dal
    Apr 2009
    Messaggi
    30

    YUYEVON & ANT_ALT

    Grazie mille i vostri esempi sono stati abbastanza chiari e mi hanno soddisfatto, ho chiarito il mio quesito..

    Grazie mille ancora!

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320

    Moderazione

    Come da Regolamento interno, il linguaggio va obbligatoriamente indicato nel titolo ed il codice va postato usando gli appositi tag CODE.

    Sistemo io.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.