W tym artykule pokażę, jak używać wywołania systemowego fork() do tworzenia procesów potomnych w C. Zacznijmy więc.
fork() Składnia i zwracana wartość:
Składnia funkcji systemowej fork() jest następująca:
widelec pid_t(próżnia);
Funkcja systemowa fork() nie przyjmuje żadnego argumentu. Zwraca liczbę całkowitą typu pid_t .
W przypadku powodzenia fork() zwraca PID procesu potomnego, który jest większy niż 0. Wewnątrz procesu potomnego zwracana jest wartość 0. Jeśli fork() się nie powiedzie, zwraca -1.
Prosty fork() Przykład:
Poniżej podano prosty przykład fork():
#włączać
#włączać
#włączać
#włączać
#włączać
intGłówny(próżnia) {
pid_t pid=widelec();
Jeśli(pid== 0) {
printf ('Dziecko => PPID: %d PID: %d ',getppid(),getpid());
Wyjście (EXIT_SUCCESS);
}
w przeciwnym razie Jeśli(pid> 0) {
printf ('Rodzic => PID: %d ',getpid());
printf („Czekam na zakończenie procesu dziecka. ');
czekać(ZERO);
printf („Proces dla dzieci zakończony. ');
}
w przeciwnym razie {
printf ('Nie można utworzyć procesu podrzędnego. ');
}
powrótEXIT_SUCCESS;
}
Tutaj użyłem fork(), aby utworzyć proces potomny z procesu głównego/nadrzędnego. Następnie wydrukowałem PID (identyfikator procesu) i PPID (identyfikator procesu nadrzędnego) z procesu podrzędnego i nadrzędnego. W procesie nadrzędnym wait(NULL) służy do oczekiwania na zakończenie procesu potomnego. W procesie potomnym exit() służy do zakończenia procesu potomnego. Jak widać, PID procesu nadrzędnego jest PPID procesu potomnego. Tak więc proces potomny 24738 należy do procesu nadrzędnego 24731 .
Możesz także użyć funkcji, aby uczynić swój program bardziej modułowym. Tutaj użyłem procesZadanie() oraz rodzicZadanie() funkcje odpowiednio dla procesów potomnych i nadrzędnych. Tak właśnie używa się fork().
#włączać#włączać
#włączać
#włączać
#włączać
próżniadzieckoZadanie() {
printf ('Witaj świecie ');
}
próżniarodzicZadanie() {
printf ('Główne zadanie. ');
}
intGłówny(próżnia) {
pid_t pid=widelec();
Jeśli(pid== 0) {
dzieckoZadanie();
Wyjście (EXIT_SUCCESS);
}
w przeciwnym razie Jeśli(pid> 0) {
czekać(ZERO);
rodzicZadanie();
}
w przeciwnym razie {
printf („Nie można utworzyć procesu podrzędnego”.);
}
powrótEXIT_SUCCESS;
}
Wyjście powyższego programu:
Uruchamianie wielu procesów potomnych za pomocą fork() i Loop:
Możesz również użyć pętli, aby utworzyć tyle procesów podrzędnych, ile potrzebujesz. W poniższym przykładzie utworzyłem 5 procesów potomnych za pomocą pętli for. Wydrukowałem również PID i PPID z procesów potomnych.
#włączać#włączać
#włączać
#włączać
#włączać
intGłówny(próżnia) {
dla(inti= 1;i<= 5;i++) {
pid_t pid=widelec();
Jeśli(pid== 0) {
printf ('Proces potomny => PPID=%d, PID=%d ',getppid(),getpid());
Wyjście (0);
}
w przeciwnym razie {
printf ('Proces nadrzędny => PID=%d ',getpid());
printf ('Oczekiwanie na zakończenie procesów podrzędnych... ');
czekać(ZERO);
printf ('proces potomny zakończony. ');
}
}
powrótEXIT_SUCCESS;
}
Jak widać, identyfikator procesu nadrzędnego jest taki sam we wszystkich procesach potomnych. Więc wszystkie należą do tego samego rodzica. Wykonują również w sposób liniowy. Jedna po drugiej. Kontrolowanie procesów potomnych to skomplikowane zadanie. Jeśli dowiesz się więcej o programowaniu systemu Linux i jego działaniu, będziesz mógł kontrolować przepływ tych procesów w dowolny sposób.
Przykład z prawdziwego życia:
Różne złożone obliczenia matematyczne, takie jak generowanie skrótów md5, sha256 itp., wymagają dużej mocy obliczeniowej. Zamiast obliczać takie rzeczy w tym samym procesie, co główny program, możesz po prostu obliczyć skrót w procesie podrzędnym i zwrócić skrót do procesu głównego.
W poniższym przykładzie wygenerowałem 4-cyfrowy kod PIN w procesie potomnym i wysłałem go do procesu nadrzędnego, czyli programu głównego. Następnie wydrukowałem stamtąd kod PIN.
#włączać#włączać
#włączać
#włączać
#włączać
intzdobądź PIN() {
// użyj PPID i PID jako nasiona
srand (getpid() +getppid());
intsekret= 1000 + wiersz () % 9000;
powrótsekret;
}
intGłówny(próżnia) {
intfd[2];
rura(fd);
pid_t pid=widelec();
Jeśli(pid> 0) {
blisko(0);
blisko(fd[1]);
po(fd[0]);
intsekretny numer;
rozmiar_treadBytes=czytać(fd[0], &sekretny numer, rozmiar(sekretny numer));
printf („Oczekiwanie na kod PIN... ');
czekać(ZERO);
printf ('Przeczytane bajty: %ld ',readBytes);
printf ('PIN: %d ',sekretny numer);
}
w przeciwnym razie Jeśli(pid== 0) {
blisko(1);
blisko(fd[0]);
po(fd[1]);
intsekret=zdobądź PIN();
pisać(fd[1], &sekret, rozmiar(sekret));
Wyjście (EXIT_SUCCESS);
}
powrótEXIT_SUCCESS;
}
Jak widać, za każdym razem, gdy uruchamiam program, otrzymuję inny 4-cyfrowy kod PIN.
Tak więc w zasadzie używa się wywołania systemowego fork() w Linuksie. Dziękuję za przeczytanie tego artykułu.