GNU/Linux >> Belajar Linux >  >> Linux

Garpu vs Klon pada 2.6 Kernel Linux

fork() adalah panggilan sistem UNIX asli. Itu hanya dapat digunakan untuk membuat proses baru, bukan utas. Selain itu, ini portabel.

Di Linux, clone() adalah panggilan sistem baru dan serbaguna yang dapat digunakan untuk membuat utas eksekusi baru. Bergantung pada opsi yang diberikan, utas eksekusi baru dapat mengikuti semantik proses UNIX, utas POSIX, sesuatu di antaranya, atau sesuatu yang sama sekali berbeda (seperti wadah yang berbeda). Anda dapat menentukan segala jenis opsi yang menentukan apakah memori, deskriptor file, berbagai ruang nama, penangan sinyal, dan sebagainya dibagikan atau disalin.

Sejak clone() adalah panggilan sistem superset, implementasi dari fork() pembungkus panggilan sistem di glibc sebenarnya memanggil clone() , tetapi ini adalah detail implementasi yang tidak perlu diketahui oleh pemrogram. fork() sebenarnya panggilan sistem masih ada di kernel Linux untuk alasan kompatibilitas mundur meskipun telah menjadi mubazir, karena program yang menggunakan libc versi lama, atau libc lain selain glibc, mungkin menggunakannya.

clone() juga digunakan untuk mengimplementasikan pthread_create() Fungsi POSIX untuk membuat utas.

Program portabel harus memanggil fork() dan pthread_create() , bukan clone() .


Tampaknya ada dua clone() hal-hal yang beredar di Linux 2.6

Ada panggilan sistem:

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

Ini adalah "clone()" yang dijelaskan dengan melakukan man 2 clone .

Jika Anda membaca halaman manual itu cukup dekat, Anda akan melihat ini:

It is actually a library function layered on top of the
underlying clone() system call.

Rupanya, Anda seharusnya mengimplementasikan threading menggunakan "fungsi perpustakaan" yang berlapis pada panggilan sistem yang namanya membingungkan.

Saya menulis program singkat:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
    pid_t cpid;
    switch (cpid = fork()) {
    case 0:   // Child process
        break;
    case -1:  // Error
        break;
    default:  // parent process
        break;
    }
    return 0;
}

Dikompilasi dengan:c99 -Wall -Wextra , dan jalankan di bawah strace -f untuk melihat apa yang sebenarnya dilakukan forking panggilan sistem. Saya mendapatkan ini dari strace pada mesin Linux 2.6.18 (x86_64 CPU):

20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0)                     = ?
20098 exit_group(0)

Tidak ada panggilan "garpu" yang muncul di strace keluaran. clone() panggilan yang muncul di strace keluaran memiliki argumen yang sangat berbeda dari klon halaman manual. child_stack=0 karena argumen pertama berbeda dari int (*fn)(void *) .

Tampaknya fork(2) panggilan sistem diimplementasikan dalam hal nyata clone() , sama seperti "fungsi perpustakaan" clone() diimplementasikan. Yang nyata clone() memiliki kumpulan argumen yang berbeda dari klon halaman manual.

Sederhananya, kedua pernyataan Anda yang tampaknya bertentangan tentang fork() dan clone() benar. Namun, "klon" yang terlibat berbeda.


fork() hanyalah sekumpulan flag tertentu untuk pemanggilan sistem clone() . clone() cukup umum untuk membuat "proses" atau "utas" atau bahkan hal-hal aneh yang berada di antara proses dan utas (misalnya, "proses" berbeda yang menggunakan tabel deskriptor file yang sama).

Intinya, untuk setiap "jenis" informasi yang terkait dengan konteks eksekusi di kernel, clone() memberi Anda pilihan untuk membuat alias informasi itu atau menyalinnya. Utas sesuai dengan aliasing, proses sesuai dengan penyalinan. Dengan menentukan kombinasi antara flag ke clone() , Anda dapat membuat hal-hal aneh yang bukan merupakan utas atau proses. Anda biasanya tidak boleh melakukan ini, dan saya membayangkan ada beberapa perdebatan selama pengembangan kernel Linux tentang apakah harus memungkinkan mekanisme umum seperti clone() .


Linux
  1. Siklus hidup pengujian kernel Linux

  2. Cara memutakhirkan Kernel di Desktop Linux

  3. Linux – Kernel:Dukungan Namespaces?

  1. Linux – Penerusan Ip Kernel?

  2. Linux – Kernel Tercemar Di Linux?

  3. Linux – Metode Panggilan Sistem di Kernel Baru?

  1. Linux – Apakah Kernel Linux/unix yang Berbeda Dapat Dipertukarkan?

  2. Memanggil fungsi userspace dari dalam modul kernel Linux

  3. Panggilan sistem Linux tercepat