Proces potomny tworzy własny proces potomny

Proces potomny tworzy własny proces potomny
NO
  • Rejestracja:około 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:56
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:

Kopiuj
#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;
}
edytowany 1x, ostatnio: flowCRANE
KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
1

Po tym, jak w:

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

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

NO
  • Rejestracja:około 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:56
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.

KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
0

Jaki tym razem problem?

NO
  • Rejestracja:około 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:56
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:

Kopiuj
#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:

Kopiuj
#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:

Kopiuj
#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:

Kopiuj
#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:

Kopiuj
//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:

Kopiuj
//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).

edytowany 1x, ostatnio: flowCRANE
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)