Proces potomny tworzy własny proces potomny

0

Witam. Mam pewien problem z działaniem mojego programu. Przyczyną może być to, że program główny tworzy dwa procesy potomne, a jeden z nich samowolnie tworzy własny proces potomny. Dlaczego tak się dzieje? Proszę o pomoc.

Oto kod programu głównego:
main.c:

#include "mem_func.h"
#include "sem_func.h"

#define SIZE 25

int main(int argc, char const *argv[])
{
    const char prod_path[]="./producer.x";
    const char prod_name[]="producer.x";
    const char cons_path[]="./consumer.x";
    const char cons_name[]="consumer.x";

    const int wait_val=2;

    if(argc<1)
    {
        perror("Za malo argumentow\n");
        exit(8);
    }

    const key_t sem_key=createSem();
    const int id_sem=semAccess(sem_key);

    const key_t mem_key=memCreate();
    const int mem_id=memAccess(mem_key, sizeof(Towar));

    const int producer=fork();
    const int consumer=fork();

    char semid[SIZE];
    char memid[SIZE];

    sprintf(semid, "%d", id_sem);
    sprintf(memid, "%d", mem_id);

    if (producer==-1 || consumer==-1)
    {
        perror("Nie udalo sie utworzyc jednego z procesow potomnych\n");
        exit(6);
    }

    else if(producer==0)
    {
        if(execl(prod_path, prod_name, semid, memid, argv[3], NULL)==-1)
        {
            perror("Nie udalo sie uruchomic procesu producenta\n");
            exit(7);
        }
    }

    else if(consumer==0)
    {
        if(execl(cons_path, cons_name, semid, memid, argv[4], NULL)==-1)
        {
            perror("Nie udalo sie uruchomic procesu kosumenta\n");
            exit(7);
        }
    }

    sleep(SLV);

    for (int i=0; i<wait_val; ++i)
    {
        int status;
        const pid_t child=wait(&status);
        printf("Proces o ID: %d zakonczyl prace z kodem: %d\n", child, status);
    }

    semDelete(id_sem, VAL2);
    //semDelete(id_sem, SEM1);
    memDel(mem_id);

    return 0;
}
1

Po tym, jak w:

    const int producer=fork();
    const int consumer=fork();

Tworzysz producenta, to oba procesy (macierzysty i producent) tworzą konsumenta.

0

Dzięki za pomoc :)
Przeniosłem tworzenie procesu konsumenta za instrukcje warunkowe dla producenta. W tej chwili mam dwa procesy potomne, ale niestety problem tkwi gdzie indziej.

0

Jaki tym razem problem?

0

Problem producenta i konsumenta z użyciem semaforów, pamięci dzielonej. Program zatrzymuje się po wejściu do sekcji krytycznej. Po zmianie semaforów w funkcji setValue (na końcu sekcji krytycznej) program wykonuje się do końca, ale plik wynikowy jest pusty. Prawdopodobnie napiszę obie sekcje krytyczne od nowa, na pewno zamienię semafory binarne na ogólne (informujące kolejno o pełnym i pustym buforze), tak by oba procesy mogły operować na pojedynczych (różnych od siebie) elementach bufora.

prod.c:

#include "mem_func.h"
#include "sem_func.h"

int main(int argc, char const *argv[])
{
    const int id_sem=atoi(argv[1]);
    const int mem_id=atoi(argv[2]);

    char buf[BUF_SIZE];

    const int file1=open(argv[3], O_RDONLY, 0644);
    if(file1==-1)
    {
        perror("Blad funkcji open() - proc. producenta\n");
        exit(9);
    }

    Towar *bufor;
    bufor=(Towar*) memAtt(mem_id, O_WRONLY);

    /*bufor[0].begin=0;
    bufor[0].end=0;*/

    setValue(id_sem, SEM0, VAL);

    int bytes_read=0;
    int bytes_written=0;

    do
    {
        bufor->begin=0;
        bufor->end=0;

        bytes_read=read(file1, buf, sizeof(buf));
        if(bytes_read==-1)
        {
            perror("Producent nie moze odczytac pliku\n");
            exit(10);
        }

        bytes_written=0;

        while(bytes_written<bytes_read)
        {
            down(id_sem, SEM0);
            printf("Producent - sekcja krytyczna\n");
            int i=0;
            bufor->share[bufor->end]=buf[i];
            ++bytes_written;
            ++bufor->end;
            //bufor->share[bufor->end]='\0';
            ++i;
            up(id_sem, SEM1);
        }

    }while(bytes_read>0);

    if(close(file1)==-1)
    {
        perror("Blad funkcji close() - proces producenta\n");
        exit(11);
    }
    delAtt(bufor);

    return 0;
}

kons.c:

#include "mem_func.h"
#include "sem_func.h"

int main(int argc, char const *argv[])
{
    const int id_sem=atoi(argv[1]);
    const int mem_id=atoi(argv[2]);

    char buf[BUF_SIZE];

    const int file2=open(argv[3], O_WRONLY|O_CREAT, 0644);
    if(file2==-1)
    {
        perror("Blad funkcji open() - proc. konsumenta\n");
        exit(9);
    }

    Towar *bufor;
    bufor=(Towar*) memAtt(mem_id, O_RDONLY);

    bufor->begin=0;
    bufor->end=0;

    setValue(id_sem, SEM1, VAL);

    int bytes_read=0;
    int bytes_written=0;

    do
    {
        down(id_sem, SEM1);
        printf("Konsument - sekcja krytyczna\n");
        bytes_read=read(bufor->share[bufor->begin], buf, 1);
        if(bytes_read==-1)
        {
            perror("Blad funkcji read() - proces konsumenta\n");
            exit(10);
        }
        ++bufor->begin;
        if(bufor->begin==49)
        {
            bufor->begin=0;
        }
        up(id_sem, SEM0);

        bytes_written=0;

        ssize_t ret=(file2, buf+bytes_written, bytes_read-bytes_written);
        if(ret==-1)
        {
            perror("Blad funkcji write()\n");
            exit(11);
        }
        printf("%s\n", buf);
        bytes_written+=ret;

    }while(bytes_read>0);

    if(close(file2)==-1)
    {
        perror("Blad funkcji close() - proces konsumenta\n");
        exit(11);
    }

    delAtt(bufor);

    return 0;
}

memfc.c:

#include "mem_func.h"

int memCreate()
{
    const int key=ftok(PATH, 'b');
    if(key==-1)
    {
        perror("Blad funkcji memCreate\n");
        exit(12);
    }

    return key;
}

int memAccess(int key, int size)
{
    const int mem_id=shmget(key, size, IPC_CREAT|IPC_EXCL|MODE);
    if(mem_id==-1)
    {
        perror("Blad funkcji memAccess\n");
        exit(13);
    }

    return mem_id;
}

void memDel(int mem_id)
{
    struct shmid_ds buf;
    if(shmctl(mem_id, IPC_RMID, (struct shmid_ds*)0)==-1)
    {
        perror("Blad funkcji memDel()\n");
        exit(14);
    }

    else printf("Usunieto pamiec dzielona\n");
}

void *memAtt(int mem_id, int mode)
{
    void *shm=shmat(mem_id, NULL, mode);
    if(shm==(void*)-1)
    {
        fprintf(stderr, "Blad funkcji memAtt()\n");
        exit(15);
    }

    else printf("Utworzono dowiazanie\n");

    return shm;
}

void delAtt(void *shm)
{
    if(shmdt(shm)==-1)
    {
        fprintf(stderr, "Blad funkcji delAtt()\n");
        exit(16);
    }
    else printf("Usunieto dowiazanie\n");
}

int memSize(int mem_id)
{
    struct shmid_ds x;
    if(shmctl(mem_id, IPC_STAT, &x)==-1)
    {
        perror("Blad funkcji memSize()\n");
        exit(17);
    }
    
    return x.shm_segsz;
}

semfc.c:

#include "sem_func.h"
#define SEM_NR 2            //liczba semaforów
#define MODE 0600           //tryb
#define PATH "./main.x"   //ścieżka pliku dla funkcji ftok()

int semAccess(key_t key)
{
    int semid;
    semid=semget(key, SEM_NR, IPC_CREAT|MODE);
    if(semid==-1)
    {
        perror("Blad funkcji semAccess()\n");
        exit(4);
    }
    return semid;
}

void setValue(int semid, int nsem, int val)
{
    union semun ctrl;
    ctrl.val=val;
    if(semctl(semid, nsem, SETVAL, ctrl)==-1)  //SETVAL orzymuje wartość 1
    {
        perror("Blad funkcji setValue()\n");
        exit(5);
    }
}

void up(int semid, int nsem)
{
    struct sembuf do_op = {
	.sem_num=nsem,
	.sem_op=1,
	.sem_flg=0
	};
    //struktura zawiera kolejno: nr semafora, operację, flagę
    //czyli: semnum, sem_op, sem_flg
    //0 - operacja blokująca
    if(semop(semid, &do_op, VAL)==-1)
    {
        perror("Blad funkcji up()\n");
        exit(2);
    }
}

void down(int semid, int nsem)
{
    struct sembuf do_op = {
	.sem_num=nsem,
	.sem_op=-1,
	.sem_flg=0
	};

    if(semop(semid, &do_op, VAL)==-1)
    {
        perror("Blad funkcji down()\n");
        exit(2);
    }
}

void semDelete(int semid, int nsem)   //usuwanie semafora
{
    if(semctl(semid, nsem, IPC_RMID)==-1)   //obsługa błędów
    {
        perror("Blad funkcji semDelete\n");
        exit(1);
    }
    else    //komunikat
    {
        printf("Semafor zostal usuniety\n");
    }
}

key_t createSem()   //uzyskanie dostępu do semafora
{
    int key;
    if((key=ftok(PATH, 'a'))==-1)
    {
        perror("Blad funkcji createSem()\n");
        exit(3);
    }
    return key;
}

memfc.h:

//biblioteka dla pamięci dzielonej

#ifndef MEM_FUNC_H
#define MEM_FUNC_H

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PATH "./consumer.x"
#define MODE 0600
#define MEM_SIZE 50
#define BUF_SIZE 50

typedef struct
{
    char share[MEM_SIZE];
    int begin;
    int end;
} Towar;


int memCreate();	                //tworzenie pamięci dzielonej
int memAccess(int key, int size);	//dostęp do pamięci dzielonej
void memDel(int mem_id);			//usuwanie pamięci dzielonej
void *memAtt(int mem_id, int mode); //tworzenie dowiązania
void delAtt(void *mem_id);          //usuwanie dowiązania
int memSize(int mem_id);			//rozmiar pamięci dzielonej

#endif

semfc.h:

//biblioteka dla semaforów

#ifndef SEM_FUNC_H
#define SEM_FUNC_H

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <time.h>

#ifdef _SEM_SEMUN_UNDEFINED

union semun {
int val;				    //wartosc dla SETVAL
struct semid_ds *buf;	    //bufor dla IPC_STAT, IPC_SET
unsigned short *array;	    //tablica dla GETALL, SETALL
struct seminfo *__buf;	    //bufor dla IPC_INFO (specyfika Linuksa)
};

#endif  //_SEM_SEMUN_UNDEFINED

enum {SEM0, SEM1, VAL=1, VAL2, SLV=5};

int semAccess(key_t key);   //utworzenie semafora
void setValue(int semid, int nsem, int val);
//przypisanie wartośći (inicjalizacja)

void up(int semid, int nsem);         //podniesienie semafora...
void down(int semid, int nsem);       //...i jego opuszczenie
key_t createSem();                    //dostęp do semafora
//int queue(int semid);               //kolejka
void semDelete(int semid, int nsem);  //usunięcie semafora

#endif  //FUNC_H

Prosiłbym o sprawdzenie kodu pod kątem błędów (oczywiście bez sekcji krytycznych, które idą do kosza).

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