Note that there are some explanatory texts on larger screens.

plurals
  1. POProcess is killed without a (obvious) reason and program stops working
    primarykey
    data
    text
    <p>Here's what my program is supposed to do:</p> <p>create 4 child processes:</p> <p>process 0 is reading 1 byte at a time from STDIN, then writing it into FIFO</p> <p>process 1 is reading this 1 byte from fifo and write its value as HEX into shared memory</p> <p>process 2 is reading HEX value from shared memory and writing it into pipe</p> <p>finally process 3 is reading from pipe and writing into STDOUT (in my case: terminal)</p> <p>I can't change communication channels. FIFO, then shared memory, then pipes are the only option.</p> <p><strong>My problem:</strong> Program stops at random moments when some file is directed into stdin (for example:./program &lt; /dev/urandom). Sometimes after writing 5 HEX values, sometimes after 100. Weird thing is that when it is working and in another terminal I write "pstree -c" there is 1 main process with 4 children processes (which is what I want), but when I write "pstree -c" after it stopped writing (but still runs) there are only 3 child processes. For some reason 1 is gone even though they all have while(1) in them..</p> <p>I think I might have problem with synchronization here, but I am unable to spot it (I've tried for many hours). </p> <p>Here's the code:</p> <pre><code>#include &lt;unistd.h&gt; #include &lt;fcntl.h&gt; #include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;stdlib.h&gt; #include &lt;sys/shm.h&gt; #include &lt;sys/sem.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/wait.h&gt; #include &lt;sys/stat.h&gt; #include &lt;string.h&gt; #include &lt;signal.h&gt; #define BUFSIZE 1 #define R 0 #define W 1 // processes ID pid_t p0, p1, p2, p3; // FIFO variables int fifo_fd; unsigned char bufor[BUFSIZE] = {}; unsigned char bufor1[BUFSIZE] = {}; // Shared memory variables key_t key; int shmid; char * tab; // zmienne do pipes int file_des[2]; char bufor_pipe[BUFSIZE*30] = {}; void proces0() { ssize_t n; while(1) { fifo_fd = open("/tmp/fifo",O_WRONLY); if(fifo_fd == -1) { perror("blad przy otwieraniu kolejki FIFO w p0\n"); exit(1); } n = read(STDIN_FILENO, bufor, BUFSIZE); if(n&lt;0) { perror("read error w p0\n"); exit(1); } if(n &gt; 0) { if(write(fifo_fd, bufor, n) != n) { perror("blad zapisu do kolejki fifo w p0\n"); exit(1); } memset(bufor, 0, n); // czyszczenie bufora } close(fifo_fd); } } void proces1() { ssize_t m, x; char wartosc_hex[30] = {}; while(1) { if(tab[0] == 0) { fifo_fd = open("/tmp/fifo", O_RDONLY); // otwiera plik typu fifo do odczytu if(fifo_fd == -1) { perror("blad przy otwieraniu kolejki FIFO w p1\n"); exit(1); } m = read(fifo_fd, bufor1, BUFSIZE); x = m; if(x &lt; 0) { perror("read error p1\n"); exit(1); } if(x &gt; 0) { // Konwersja na HEX if(bufor1[0] &lt; 16) { if(bufor1[0] == 10) // gdy enter { sprintf(wartosc_hex, "0x0%X\n", bufor1[0]); } else { sprintf(wartosc_hex, "0x0%X ", bufor1[0]); } } else { sprintf(wartosc_hex, "0x%X ", bufor1[0]); } // poczekaj az pamiec bedzie pusta (gotowa do zapisu) strcpy(&amp;tab[0], wartosc_hex); memset(bufor1, 0, sizeof(bufor1)); // czyszczenie bufora memset(wartosc_hex, 0, sizeof(wartosc_hex)); // przygotowanie tablicy na zapis wartosci hex x = 0; } close(fifo_fd); } } } void proces2() { close(file_des[0]); // zablokuj kanal do odczytu while(1) { if(tab[0] != 0) { if(write(file_des[1], tab, strlen(tab)) != strlen(tab)) { perror("blad write w p2"); exit(1); } // wyczysc pamiec dzielona by przyjac kolejny bajt memset(tab, 0, sizeof(tab)); } } } void proces3() { ssize_t n; close(file_des[1]); // zablokuj kanal do zapisu while(1) { if(tab[0] == 0) { if((n = read(file_des[0], bufor_pipe, sizeof(bufor_pipe))) &gt; 0) { if(write(STDOUT_FILENO, bufor_pipe, n) != n) { perror("write error w proces3()"); exit(1); } memset(bufor_pipe, 0, sizeof(bufor_pipe)); } } } } int main(void) { key = 5678; int status; // Tworzenie plikow przechowujacych ID procesow int des_pid[2] = {}; char bufor_proces[50] = {}; mknod("pid0", S_IFREG | 0777, 0); mknod("pid1", S_IFREG | 0777, 0); mknod("pid2", S_IFREG | 0777, 0); mknod("pid3", S_IFREG | 0777, 0); // Tworzenie semaforow key_t klucz; klucz = ftok(".", 'a'); // na podstawie pliku i pojedynczego znaku id wyznacza klucz semafora if(klucz == -1) { perror("blad wyznaczania klucza semafora"); exit(1); } semafor = semget(klucz, 1, IPC_CREAT | 0777); // tworzy na podstawie klucza semafor. 1 - ilosc semaforow if(semafor == -1) { perror("blad przy tworzeniu semafora"); exit(1); } if(semctl(semafor, 0, SETVAL, 0) == -1) // ustawia poczatkowa wartosc semafora (klucz, numer w zbiorze od 0, polecenie, argument 0/1/2) { perror("blad przy ustawianiu wartosci poczatkowej semafora"); exit(1); } // Tworzenie lacza nazwanego FIFO if(access("/tmp/fifo", F_OK) == -1) // sprawdza czy plik istnieje, jesli nie - tworzy go { if(mkfifo("/tmp/fifo", 0777) != 0) { perror("blad tworzenia FIFO w main"); exit(1); } } // Tworzenie pamieci dzielonej // Lista pamieci wspoldzielonych, komenda "ipcs" // usuwanie pamieci wspoldzielonej, komenta "ipcrm -m ID_PAMIECI" shmid = shmget(key, (BUFSIZE*30), 0666 | IPC_CREAT); if(shmid == -1) { perror("shmget"); exit(1); } tab = (char *) shmat(shmid, NULL, 0); if(tab == (char *)(-1)) { perror("shmat"); exit(1); } memset(tab, 0, (BUFSIZE*30)); // Tworzenie lacza nienazwanego pipe if(pipe(file_des) == -1) { perror("pipe"); exit(1); } // Tworzenie procesow potomnych if(!(p0 = fork())) { des_pid[W] = open("pid0", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt sprintf(bufor_proces, "Proces0 ma ID: %d\n", getpid()); if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces)) { perror("blad przy zapisie pid do pliku w p0"); exit(1); } close(des_pid[W]); proces0(); } else if(p0 == -1) { perror("blad przy p0 fork w main"); exit(1); } else { if(!(p1 = fork())) { des_pid[W] = open("pid1", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt sprintf(bufor_proces, "Proces1 ma ID: %d\n", getpid()); if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces)) { perror("blad przy zapisie pid do pliku w p1"); exit(1); } close(des_pid[W]); proces1(); } else if(p1 == -1) { perror("blad przy p1 fork w main"); exit(1); } else { if(!(p2 = fork())) { des_pid[W] = open("pid2", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt sprintf(bufor_proces, "Proces2 ma ID: %d\n", getpid()); if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces)) { perror("blad przy zapisie pid do pliku w p2"); exit(1); } close(des_pid[W]); proces2(); } else if(p2 == -1) { perror("blad przy p2 fork w main"); exit(1); } else { if(!(p3 = fork())) { des_pid[W] = open("pid3", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt sprintf(bufor_proces, "Proces3 ma ID: %d\n", getpid()); if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces)) { perror("blad przy zapisie pid do pliku w p3"); exit(1); } close(des_pid[W]); proces3(); } else if(p3 == -1) { perror("blad przy p3 fork w main"); exit(1); } else { // proces macierzysty waitpid(p0, &amp;status, 0); waitpid(p1, &amp;status, 0); waitpid(p2, &amp;status, 0); waitpid(p3, &amp;status, 0); //wait(NULL); unlink("/tmp/fifo"); shmdt(tab); // odlaczenie pamieci dzielonej shmctl(shmid, IPC_RMID, NULL); // usuwanie pamieci wspoldzielonej printf("\nKONIEC PROGRAMU\n"); } } } } exit(0); } </code></pre> <p>after using "strace ./projekt_wlasciwy &lt; /dev/urandom" I've got something like this:</p> <pre><code>clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e2e728) = 26916 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e2e728) = 26917 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e2e728) = 26918 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e2e728) = 26919 waitpid(26916, 0xAA 0xC1 0x84 0x9C 0x4E 0x0D 0x54 0xB2 0xE7 0x19 0x22 0xA0 0x2E 0xF0 0x1C 0xC4 0xDF 0x21 0xA2 0xB4 0x3B 0xEE [{WIFSIGNALED(s) &amp;&amp; WTERMSIG(s) == SIGPIPE}], 0) = 26916 --- SIGCHLD (Child exited) @ 0 (0) --- waitpid(26917, 0x40 0xbfb083a8, 0) = ? ERESTARTSYS (To be restarted) --- SIGWINCH (Window changed) @ 0 (0) --- waitpid(26917, [{WIFSIGNALED(s) &amp;&amp; WTERMSIG(s) == SIGTERM}], 0) = 26917 --- SIGTERM (Terminated) @ 0 (0) --- +++ killed by SIGTERM +++ </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload