GNU/Linux >> Belajar Linux >  >> Linux

Proses Linux – ID Proses, fork, execv, wait, waitpid Fungsi C

Dalam artikel ini, kita akan mulai dari penjelasan kecil tentang ID proses dan kemudian kita akan segera beralih ke aspek praktis di mana-di mana kita akan membahas beberapa fungsi C terkait proses seperti fork(), execv() dan wait() .

Seri Proses Linux:bagian 1, bagian 2, bagian 3 (artikel ini).

ID Proses

ID Proses adalah pengidentifikasi proses yang merupakan angka non-negatif yang terkait dengan suatu proses. Angka-angka ini unik di seluruh proses yang berjalan di sistem.

Keunikan ID proses ini terkadang digunakan oleh proses untuk membuat beberapa nama file yang unik. Ketika sebuah proses dihentikan dari sistem, ID prosesnya tersedia untuk digunakan kembali.

Tetapi ada penundaan khusus yang diperhitungkan sebelum membuat ID proses tersedia untuk digunakan kembali. Ini karena ID proses yang terkait dengan proses sebelumnya yang sekarang dihentikan mungkin digunakan dalam bentuk nama file, dll. Jadi, penundaan ditambahkan sebelum menggunakan kembali ID proses yang sama.

ID Proses  1 adalah untuk proses init. Ini adalah proses pertama yang dimulai setelah sistem boot.

File program untuk proses init dapat ditemukan di /etc/init atau di /sbin/init. Proses init adalah proses tingkat pengguna tetapi berjalan dengan hak akses root dan bertanggung jawab untuk membawa sistem ke status setelah kernel di-bootstrap. File startup yang dibaca oleh proses init untuk mencapai status tertentu adalah

  • /etc/rc*.d
  • /etc/init.d
  • /etc/inittab

ID Proses 0 adalah penjadwal sistem. Ini adalah proses tingkat kernel yang bertanggung jawab atas semua penjadwalan proses yang terjadi di dalam sistem.

Fungsi Kontrol Proses

Fungsi garpu()

Seperti yang telah dibahas dalam artikel membuat proses daemon di C, fork fungsi digunakan untuk membuat proses dari dalam proses.

Proses baru yang dihasilkan oleh fork() dikenal sebagai proses anak sedangkan proses asli (dari mana fork() dipanggil) menjadi proses induk.

Fungsi fork() dipanggil sekali (dalam proses induk) tetapi kembali dua kali. Setelah kembali dalam proses induk sedangkan yang kedua kembali dalam proses anak. Perhatikan bahwa urutan eksekusi orang tua dan anak dapat bervariasi tergantung pada algoritma penjadwalan proses. Jadi kita melihat bahwa fungsi fork digunakan dalam pembuatan proses .

Tanda tangan dari fork() adalah  :

pid_t fork(void);

Keluarga Fungsi eksekutif

Kumpulan fungsi lain yang umumnya digunakan untuk membuat proses adalah exec keluarga fungsi. Fungsi-fungsi ini terutama digunakan jika ada persyaratan untuk menjalankan biner yang ada dari dalam suatu proses.

Misalnya, kita ingin menjalankan perintah 'whoami' dari dalam suatu proses, maka dalam skenario semacam ini fungsi exec() atau anggota lain dari keluarga ini digunakan. Poin yang perlu diperhatikan di sini adalah bahwa dengan panggilan ke salah satu keluarga fungsi exec, gambar proses saat ini diganti dengan gambar proses baru.

Anggota umum dari keluarga ini adalah fungsi execv(). Tanda tangannya adalah :

int execv(const char *path, char *const argv[]);

Catatan :Silakan merujuk ke halaman manual exec untuk melihat anggota lain dari keluarga ini.

Fungsi wait() dan waitpid()

Ada situasi tertentu di mana ketika proses anak berakhir atau berubah status maka proses induk harus mengetahui tentang perubahan status atau status penghentian proses anak. Dalam hal ini berfungsi seperti wait() digunakan oleh proses induk di mana induk dapat menanyakan perubahan status proses anak menggunakan fungsi-fungsi ini.

Tanda tangan wait() adalah  :

pid_t wait(int *status);

Untuk kasus di mana proses induk memiliki lebih dari satu proses anak, ada fungsi waitpid() yang dapat digunakan oleh proses induk untuk menanyakan status perubahan anak tertentu.

Tanda tangan waitpid() adalah :

pid_t waitpid(pid_t pid, int *status, int options);

Secara default,  waitpid() hanya menunggu turunan yang dihentikan, tetapi perilaku ini dapat dimodifikasi melalui argumen opsi, seperti yang dijelaskan di bawah ini.

Nilai pid dapat berupa:

  • <-1 :Tunggu proses anak yang ID grup prosesnya sama dengan nilai absolut pid.
  • -1 :Tunggu proses anak apa pun.
  • 0 :Tunggu proses turunan yang ID grup prosesnya sama dengan proses pemanggilan.
  • > 0 :Tunggu anak yang ID prosesnya sama dengan nilai pid.

Nilai opsi adalah OR dari nol atau lebih dari konstanta berikut:

  • WNOHANG :Segera kembali jika tidak ada anak yang keluar.
  • WUNTRACED :Juga  kembali jika anak berhenti. Status untuk anak-anak yang dilacak yang telah berhenti disediakan meskipun opsi ini tidak ditentukan.
  • WCONTINUED :Kembalikan juga jika anak yang dihentikan telah dilanjutkan dengan pengiriman SIGCONT.

Untuk informasi lebih lanjut tentang waitpid(), periksa halaman manual fungsi ini.

Contoh Program

Di sini kami memiliki contoh di mana kami telah menggunakan semua jenis fungsi yang dijelaskan di atas.

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>

int global; /* In BSS segement, will automatically be assigned '0'*/

int main()
{
    pid_t child_pid;
    int status;
    int local = 0;
    /* now create new process */
    child_pid = fork();

    if (child_pid >= 0) /* fork succeeded */
    {
        if (child_pid == 0) /* fork() returns 0 for the child process */
        {
            printf("child process!\n");

            // Increment the local and global variables
            local++;
            global++;

            printf("child PID =  %d, parent pid = %d\n", getpid(), getppid());
            printf("\n child's local = %d, child's global = %d\n",local,global);

            char *cmd[] = {"whoami",(char*)0};
            return execv("/usr/bin/",cmd); // call whoami command

         }
         else /* parent process */
         {
             printf("parent process!\n");
             printf("parent PID =  %d, child pid = %d\n", getpid(), child_pid);
             wait(&status); /* wait for child to exit, and store child's exit status */
             printf("Child exit code: %d\n", WEXITSTATUS(status));

             //The change in local and global variable in child process should not reflect here in parent process.
             printf("\n Parent'z local = %d, parent's  global = %d\n",local,global);

             printf("Parent says bye!\n");
             exit(0);  /* parent exits */
         }
    }
    else /* failure */
    {
        perror("fork");
        exit(0);
    }
}

Pada kode di atas, saya telah mencoba membuat program yang :

  • Menggunakan fork() API untuk membuat proses anak
  • Menggunakan variabel lokal dan global untuk membuktikan bahwa fork membuat salinan proses induk dan turunan memiliki salinan variabelnya sendiri untuk dikerjakan.
  • Menggunakan execv API untuk memanggil perintah 'whoami'.
  • Menggunakan wait() API untuk mendapatkan status penghentian anak di induk. Perhatikan bahwa API ini menahan eksekusi induk hingga turunan berakhir atau mengubah statusnya.

Sekarang, ketika program di atas dijalankan, menghasilkan output sebagai berikut:

$ ./fork
parent process!
parent PID =  3184, child pid = 3185
child process!
child PID =  3185, parent pid = 3184

child's local = 1, child's global = 1
himanshu
Child exit code: 0

Parent'z local = 0, parent's  global = 0
Parent says bye!

Linux
  1. Proses UNIX / Linux:C fork() Fungsi

  2. Mengelola Proses Di Ubuntu Linux

  3. Linux:Temukan dan Bunuh Proses Zombie

  1. 30 Latihan Proses Linux Untuk Sysadmin

  2. Bagaimana cara menghitung pemanfaatan CPU dari suatu proses &semua proses anaknya di Linux?

  3. Pemborosan waktu execv() dan fork()

  1. Linux – Proses Init:Leluhur Semua Proses?

  2. UNIX / Linux:3 Cara Mengirim Sinyal ke Proses

  3. Bagaimana menemukan semua proses anak?