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