IPC,semafory UNIX

0

Witam wszystkich,

Mam 3 procesy,pierwszy czyta linie ze stdin i wysyla je do drugiego procesu przez pipe. Drugi proces liczy liczbe znakow w linii i zapisuja ja do pliku.Trzeci proces odczytuje te liczbe z pliku i wypisuja ja na ekran. Dostem do pliku synchronizuje za pomoca semafów. Mój program nie do konca działa tak jak powinien tzn pierwsza linie czyta dobrze ale kiedy wpisuje kolejna zawiesza sie tzn:

na przyklad wpisuje:

aaa
3 // tu dziala dobrze
xx
//tutaj nic sie nie dzieje,nic nie wypisuje

mysle że problem jest z synchronizacja

Proszę o pomoc

Oto kod:

#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <signal.h>

 #define SEMNUMB 2
 #define KEYNB 11 // numer unikalnego identyfikatora dla pliku (ftok)

 int pid1, pid2, pid3, i;


union semun{
    int val;
    struct semid_ds *buf;
    unsigned short int* array;
    struct seminfo *__buf;
};

struct sembuf write_lock = { 0, -1, 0 };
struct sembuf write_unlock = { 0, 1, 0 };
struct sembuf read_lock = { 1, -1, 0 };
struct sembuf read_unlock = { 1, 1, 0 };

int semid; // semafor

typedef void (*sighandler_t)(int);
void sig_handler(int signum)
{
    if(signum == 1)
    {
        kill(pid2, 9);
        kill(pid3, 9);
        kill(pid1, 9);
    }


}

int main(int argc, char** argv) { 
    int fd[2]; 
    char buf[PIPE_BUF];
    FILE *test;


    key_t semkey = ftok(".", KEYNB); // generowanie unikalnego klucza dla semafora
    semid = semget(semkey, SEMNUMB, IPC_CREAT | 0666); // utworzenie semafora
    union semun op;
    op.val = 1; // zapis
    semctl(semid, 0, SETVAL, op);
    op.val = 0; // odczyt
    semctl(semid, 1, SETVAL, op);

    if (pipe(fd) < 0)
     {
        perror("blad przygotowywania lacza");
        exit(EXIT_FAILURE);
     }

     for(i=1; i<64; i++)
            {
            sighandler_t f = signal(i, sig_handler);
            }


    pid1=fork();  // utworzenie pierwszego potomka 
    if (pid1!=0)
    { 
        pid2=fork(); // utworzenie drugiego potomka 
        if (pid2!=0)
        {
            pid3=fork(); // utworzenie trzeciego potomka 
            if (pid3!=0)
            {
            //Zakonczenie procesu wywolującego  
            return 0;
            }    

            else  ///////// third child ////////////
            {
                int dlugosc=0;
                semop(semid, &read_lock, 1); 
                test = fopen("kkk.txt","r");
                fscanf(test,"%d",&dlugosc);
                fclose(test);
                semop(semid, &write_unlock, 1);
                printf("%d",dlugosc);           
            }   
        }       

        else  ////////// second child /////////
        {
                int dlugosc = 0;
                close(fd[1]); 
                while((read(fd[0] , buf, PIPE_BUF)>0))   
                {
                    dlugosc = strlen(buf)-1;
                    semop(semid, &write_lock, 1);
                    test = fopen("kkk.txt","w");
                    fprintf(test,"%d",dlugosc);
                    fclose (test);  
                    semop(semid, &read_unlock, 1);
                }

                printf("Brak danych - zakonczenie procesu odbierajacego\n");
                close(fd[0]);

        }
       }
    else ////////// First child /////////
    { 
             close(fd[0]);
             while (!feof(stdin))
             {
                fgets(buf, PIPE_BUF, stdin);
                int dlugosc = strlen(buf)-1;
                if (!feof(stdin) && dlugosc!=0) write(fd[1], buf,  PIPE_BUF);
             }

            close(fd[1]);   
            printf("Zakonczenie procesu wysylajacego\n");
    }

} 
0

mysle że problem jest z synchronizacja

Ja też tak myśle. Zredukuj do dwóch procesów usuwając trzeciego child-a oraz cały kod związany z semaforem. Jeśli problem zniknie to znaczy że semafor jest popsuty. Po co ci aż 63 wywołania signal?

1 użytkowników online, w tym zalogowanych: 0, gości: 1