Portál AbcLinuxu, 10. května 2025 05:37
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <signal.h> #include <stdio.h> #include <string.h> // odstraneni procesu drive, nez se z nej stane zombie void clean_up_child(int sig_num) { wait(NULL); printf("Odstraneni procesu.\n"); fflush(stdout); } // vytvori proces, presmeruje in na stdin a spusti prikaz // vraci cislo procesu potomka a do out ulozi vstupni FD jako vystup dat potomka int make_child(char **cmd_params, int in, int &out) { int fds[2]; pid_t pid; pipe(fds); // vytvoreni pipy pid = fork(); // vytvoreni potomka if (pid > 0) { // rodic close(fds[1]); // uzavreni vystupniho FD out = fds[0]; // vraceni vstupniho FD printf("Prikaz '%s', pid=%d, fds[0]=%d, fds[1]=%d, in=%d\n", cmd_params[0], pid, fds[0], fds[1], in); fflush(stdout); return pid; } else if (pid == 0) { // potomek close(fds[0]); // uzavreni vstupniho FD // presmerovani stdin na in close(STDIN_FILENO); dup2(in, STDIN_FILENO); close(in); // presmerovani stdout na FD close(STDOUT_FILENO); dup2(fds[1], STDOUT_FILENO); close(fds[1]); printf("Before Exec '%s'\n", cmd_params[0]); fflush(stdout); // spusteni prikazu execvp(cmd_params[0], cmd_params); return -1; // exec se vratil - vznikla chyba } else { // chyba forku return -1; } return 0; } int main(void) { // zabraneni vzniku zombie procesu /* struct sigaction sigact; memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = &clean_up_child; sigaction(SIGCHLD, &sigact, NULL); */ int out, out1, out_end, r; int r1, r2, r3; char *cmd1[] = {"ls", "-laR", "/etc", 0}; char *cmd2[] = {"sort", 0}; char *cmd3[] = {"grep", "bin", 0}; r1 = make_child(cmd1, STDIN_FILENO, out); r2 = make_child(cmd2, out, out1); r3 = make_child(cmd3, out1, out_end); char str_out[256]; if (r1 == -1 || r2 == -1 || r3 == -1) { printf("Error while making child!\n"); fflush(stdout); } // vypsani vystupu posledniho prikazu while ((r = read(out_end, str_out, 255)) > 0) write(STDOUT_FILENO, str_out, r); printf("\n"); close(out_end); return 0; }
if (pid > 0) { // rodic. Obycejne se tam i hlidaji vracene return kody. Rekl bych, ze mas problem s casovanim, ze se ti ty prikazy vykonavaji tak rychle jak to jen jde a tedy skoro paralelene a tedy si prikazy navzajem nepredavaji potrebne vstupy a vystupy. Necekaji na sebe.
... // vypsani vystupu posledniho prikazu while ((r = read(out_end, str_out, 255)) > 0) write(STDOUT_FILENO, str_out, r); printf("\n"); wait(NULL); close(out_end); return 0; }
#include <errno.h> ... do { r = read(out_end, str_out, 255); if (r == -1) { if (errno == EINTR) { continue; } else { perror("chyba pri cteni"); exit(1); } } write(STDOUT_FILENO, str_out, r); } while (r != 0);
Ten wait tam přeci vůbec nemusí být, ne? Handler vypíše, že byl potomek ukončen a program skončí.Potomka - zombie odstraní pouze příkaz wait nebo jeho odvozenina. Handler bez funkčního volání příkazu wait si může vypisovat co chce, ale potomka - zombie určite neodstraní.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.