Diğer Süreçler
Şimdiye kadar süreçler, yaratılışı, ebeveyn ve çocuk süreçleri vb. Hakkında tartıştık. Yetim süreci, Zombi süreci ve Daemon süreci gibi diğer ilgili süreçler tartışılmadan tartışma tamamlanmayacaktır.
Yetim Süreci
İsminden de anlaşılacağı üzere yetim, ebeveynsiz süreci ifade eder. Bir programı veya uygulamayı çalıştırdığımızda, uygulamanın ana süreci kabuktur. Fork () kullanarak bir süreç oluşturduğumuzda, yeni oluşturulan süreç çocuk süreçtir ve çocuğu oluşturan süreç de üst süreçtir. Buna karşılık, bunun ana süreci kabuktur. Tabii ki, tüm süreçlerin ebeveyni init işlemidir (İşlem Kimliği → 1).
Yukarıdakiler olağan bir senaryodur, ancak üst süreç alt süreçten önce çıkarsa ne olur. Sonuç, çocuk süreç artık öksüz süreç haline geliyor. Öyleyse, üstünden ne haber, yeni ebeveyni tüm süreçlerin ebeveynidir, ki bu da init sürecinden başka bir şey değildir (İşlem Kimliği - 1).
Aşağıdaki örneği kullanarak bunu deneyip anlamaya çalışalım.
/ * Dosya Adı: orphan_process.c * /
#include<stdio.h>
#include<stdlib.h>
int main() {
int pid;
system("ps -f");
pid = fork();
if (pid == 0) {
printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
sleep(5);
printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
system("ps -f");
} else {
printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
sleep(2);
exit(0);
}
return 0;
}
Derleme ve Yürütme Adımları
UID PID PPID C STIME TTY TIME CMD
4581875 180558 0 0 09:19 ? 00:00:00 sh -c cd /home/cg/root/4581875;
timeout 10s main
4581875 180564 180558 0 09:19 ? 00:00:00 timeout 10s main
4581875 180565 180564 0 09:19 ? 00:00:00 main
4581875 180566 180565 0 09:19 ? 00:00:00 ps -f
Parent: pid is 180565 and ppid is 180564
UID PID PPID C STIME TTY TIME CMD
4581875 180567 0 0 09:19 ? 00:00:00 main
4581875 180820 180567 0 09:19 ? 00:00:00 ps -f
Child: pid is 180567 and ppid is 180565
Child: pid is 180567 and ppid is 0
Zombi Süreci
Basit bir ifadeyle, ana ve alt süreç olmak üzere iki işleminiz olduğunu varsayalım. Alt süreci beklemek ve ardından süreç tablosundan alt süreç girişini temizlemek ana sürecin sorumluluğundadır. Ya ana süreç çocuk sürecini beklemeye hazır değilse ve bu arada çocuk süreç işini bitirip çıkarsa? Şimdi, çocuk süreci zombi süreci haline gelecekti. Elbette zombi süreci ana süreç hazır olduktan sonra temizlenir.
Bunu bir örnek yardımıyla anlayalım.
/ * Dosya Adı: zombie_process.c * /
#include<stdio.h>
#include<stdlib.h>
int main() {
int pid;
pid = fork();
if (pid == 0) {
system("ps -f");
printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
exit(0);
} else {
printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
sleep(10);
system("ps aux|grep Z");
}
return 0;
}
Derleme ve Yürütme Adımları
UID PID PPID C STIME TTY TIME CMD
4581875 184946 0 0 09:20 ? 00:00:00 sh -c cd /home/cg/root/4581875;
timeout 10s main
4581875 184952 184946 0 09:20 ? 00:00:00 timeout 10s main
4581875 184953 184952 0 09:20 ? 00:00:00 main
4581875 184954 184953 0 09:20 ? 00:00:00 main
4581875 184955 184954 0 09:20 ? 00:00:00 ps -f
Child: pid is 184954 and ppid is 184953
Daemon Süreci
Basit bir ifadeyle, ilişkili herhangi bir kabuğu veya terminali olmayan süreç, arka plan programı süreci olarak bilinir. Bu neden gerekli? Bunlar, eylemleri önceden tanımlanmış aralıklarla gerçekleştirmek ve ayrıca belirli olaylara yanıt vermek için arka planda çalışan işlemlerdir. Arka planda çalışan bir süreç olarak çalıştığından, arka plan programı süreci herhangi bir kullanıcı etkileşimi içermemelidir.
Dahili Linux arka plan programı işlemleri genellikle Kernel Daemons (ksoftirqd, kblockd, kswapd, vb.), Printing Daemon (cupd, lpd, vb.), Dosya Hizmeti Daemonları (smbd, nmbd, vb.) Gibi "d" harfiyle biter. , Yönetim veritabanı arka plan programları (ypbind, ypserv, vb.), Elektronik Posta Daemonları (sendmail, popd, smtpd, vb.), Uzaktan Oturum Açma ve Komut Yürütme Daemonları (sshd, in.telnetd, vb.), Önyükleme ve Yapılandırma Arka Plan Programları (dhcpd , udevd, vb.), init işlemi (init), cron daemon, atd daemon vb.
Şimdi bir daemon sürecinin nasıl oluşturulacağını görelim. Adımlar aşağıdadır -
Step 1- Bir çocuk süreci oluşturun. Şimdi iki sürecimiz var - ana süreç ve alt süreç
Genellikle süreç hiyerarşisi SHELL → EBEVEYN SÜRECİ → ÇOCUK SÜRECİ şeklindedir
Step 2- Çıkarak ana süreci sonlandırın. Alt süreç artık öksüz süreç haline gelir ve init süreci tarafından devralınır.
Şimdi hiyerarşi INIT PROCESS → CHILD PROCESS şeklindedir
Step 3- Çağıran süreç bir süreç grubu lideri değilse, setid () sistem çağrısının çağrılması yeni bir oturum oluşturur. Artık çağrı süreci, yeni oturumun grup lideri haline gelir. Bu süreç, bu yeni süreç grubundaki ve bu yeni oturumdaki tek süreç olacaktır.
Step 4 - İşlem grup kimliğini ve oturum kimliğini arama işleminin PID'sine ayarlayın.
Step 5 - Terminal ve kabuğun uygulamayla bağlantısı artık kesildiğinden, sürecin varsayılan dosya tanımlayıcılarını (standart giriş, standart çıkış ve standart hata) kapatın.
/ * Dosya adı: daemon_test.c * /
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char *argv[]) {
pid_t pid;
int counter;
int fd;
int max_iterations;
char buffer[100];
if (argc < 2)
max_iterations = 5;
else {
max_iterations = atoi(argv[1]);
if ( (max_iterations <= 0) || (max_iterations > 20) )
max_iterations = 10;
}
pid = fork();
// Unable to create child process
if (pid < 0) {
perror("fork error\n");
exit(1);
}
// Child process
if (pid == 0) {
fd = open("/tmp/DAEMON.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (fd == -1) {
perror("daemon txt file open error\n");
return 1;
}
printf("Child: pid is %d and ppid is %d\n", getpid(), getppid());
printf("\nChild process before becoming session leader\n");
sprintf(buffer, "ps -ef|grep %s", argv[0]);
system(buffer);
setsid();
printf("\nChild process after becoming session leader\n");
sprintf(buffer, "ps -ef|grep %s", argv[0]);
system(buffer);
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
} else {
printf("Parent: pid is %d and ppid is %d\n", getpid(), getppid());
printf("Parent: Exiting\n");
exit(0);
}
// Executing max_iteration times
for (counter = 0; counter < max_iterations; counter++) {
sprintf(buffer, "Daemon process: pid is %d and ppid is %d\n", getpid(), getppid());
write(fd, buffer, strlen(buffer));
sleep(2);
}
strcpy(buffer, "Done\n");
write(fd, buffer, strlen(buffer));
// Can't print this as file descriptors are already closed
printf("DoneDone\n");
close(fd);
return 0;
}
Parent: pid is 193524 and ppid is 193523
Parent: Exiting
4581875 193525 0 0 09:23 ? 00:00:00 main
4581875 193526 193525 0 09:23 ? 00:00:00 sh -c ps -ef|grep main
4581875 193528 193526 0 09:23 ? 00:00:00 grep main
4581875 193525 0 0 09:23 ? 00:00:00 main
4581875 193529 193525 0 09:23 ? 00:00:00 sh -c ps -ef|grep main
4581875 193531 193529 0 09:23 ? 00:00:00 grep main