Linus Torvalds (torvalds@cs.helsinki.fi)
Sel, 6 Agustus 1996 12:47:31 +300 (EET DST)
Pesan diurutkan berdasarkan: [tanggal] [utas] [subjek] [penulis]
Pesan berikutnya: Bernd P. Ziller: "Re: Ups di get_hash_table"
Pesan sebelumnya: Linus Torvalds: "Re: I / O request booking"
On Mon, 5 Agustus 1996, Peter P. Eiserloh menulis:
Kita perlu menjaga konsep benang tetap jelas. Terlalu banyak orang tampaknya mengacaukan utas dengan suatu proses. Diskusi berikut ini tidak mencerminkan keadaan linux saat ini, tetapi lebih merupakan upaya untuk tetap pada diskusi tingkat tinggi.
TIDAK!
Tidak ada alasan untuk berpikir bahwa "utas" dan "proses" adalah entitas yang terpisah. Begitulah cara tradisional dilakukan, tetapi saya pribadi berpikir itu adalah kesalahan besar untuk berpikir seperti itu. Satu-satunya alasan untuk berpikir seperti itu adalah bagasi bersejarah.
Baik utas dan proses benar-benar hanya satu hal: "konteks eksekusi". Mencoba membedakan kasus yang berbeda secara artifisial hanya bisa dilakukan sendiri.
"Konteks eksekusi", dengan ini disebut COE, hanyalah konglomerat dari semua keadaan COE itu. Keadaan itu mencakup hal-hal seperti keadaan CPU (register dll), keadaan MMU (pemetaan halaman), keadaan perizinan (uid, gid) dan berbagai "keadaan komunikasi" (file terbuka, penangan sinyal, dll). Secara tradisional, perbedaan antara "utas" dan "proses" terutama adalah bahwa utas memiliki status CPU (+ mungkin beberapa kondisi minimal lainnya), sementara semua konteks lainnya berasal dari proses. Namun, itu baru
satu cara untuk membagi keadaan total COE, dan tidak ada yang mengatakan bahwa itu adalah cara yang tepat untuk melakukannya. Membatasi diri Anda dengan citra seperti itu benar-benar bodoh.
Cara Linux berpikir tentang hal ini (dan seperti yang saya inginkan hal yang kerja) adalah bahwa ada adalah tidak ada hal seperti itu sebagai "proses" atau "benang". Hanya ada totalitas COE (disebut "tugas" oleh Linux). COE yang berbeda dapat berbagi bagian dari konteksnya satu sama lain, dan satu subset dari berbagi itu adalah pengaturan "utas" / "proses" tradisional, tetapi itu harus benar-benar dilihat sebagai HANYA subset (ini adalah subset yang penting, tetapi yang penting datang bukan dari desain, tetapi dari standar: kami jelas ingin menjalankan program utas yang sesuai standar di atas Linux juga).
Singkatnya: JANGAN mendesain di sekitar utas / proses cara berpikir. Kernel harus dirancang di sekitar cara berpikir COE, dan kemudian pthreads library dapat mengekspor antarmuka pthreads terbatas ke pengguna yang ingin menggunakan cara memandang COE itu.
Sama seperti contoh apa yang menjadi mungkin ketika Anda berpikir COE sebagai lawan dari utas / proses:
- Anda dapat melakukan program "cd" eksternal, sesuatu yang secara tradisional tidak mungkin di UNIX dan / atau proses / utas (contoh konyol, tetapi idenya adalah Anda dapat memiliki "modul" semacam ini yang tidak terbatas pada UNIX tradisional) / pengaturan utas). Lakukan:
clone (CLONE_VM | CLONE_FS);
child: execve ("external-cd");
/ * the "execve ()" akan melepaskan VM, jadi satu-satunya alasan kami menggunakan CLONE_VM adalah untuk membuat tindakan kloning lebih cepat * /
- Anda dapat melakukan "vfork ()" secara alami (ini memberikan dukungan kernel minimal, tetapi dukungan itu cocok dengan cara berpikir CUA dengan sempurna):
klon (CLONE_VM);
anak: terus berjalan, akhirnya mengeksekusi ()
ibu: tunggu eksekusi
- Anda dapat melakukan "IO deamons" eksternal:
clone (CLONE_FILES);
child: deskriptor file terbuka dll
ibu: gunakan fd anak dibuka dan ay.
Semua hal di atas bekerja karena Anda tidak terikat pada utas / cara berpikir. Pikirkan server web misalnya, di mana skrip CGI dilakukan sebagai "utas eksekusi". Anda tidak dapat melakukan itu dengan utas tradisional, karena utas tradisional selalu harus membagikan seluruh ruang alamat, jadi Anda harus menautkan semua yang ingin Anda lakukan di server web itu sendiri ("utas" tidak dapat berjalan dieksekusi lainnya).
Memikirkan hal ini sebagai masalah "konteks eksekusi", tugas Anda sekarang dapat memilih untuk mengeksekusi program eksternal (= pisahkan ruang alamat dari orang tua) dll jika mereka mau, atau mereka dapat misalnya berbagi semuanya dengan orang tua kecuali untuk deskriptor file (sehingga sub-"utas" dapat membuka banyak file tanpa orang tua perlu khawatir tentang mereka: mereka menutup secara otomatis ketika sub-"utas" keluar, dan itu tidak menggunakan fd di induknya) .
Pikirkan "inetd" yang berulir, misalnya. Anda ingin fork + exec overhead rendah, jadi dengan cara Linux Anda bisa daripada menggunakan "fork ()" Anda menulis inetd multi-threaded di mana setiap utas dibuat hanya dengan CLONE_VM (ruang alamat berbagi, tetapi jangan berbagi file deskriptor dll). Kemudian anak dapat mengeksekusi jika itu adalah layanan eksternal (rlogind, misalnya), atau mungkin itu adalah salah satu layanan internal inetd (echo, timeofday) dalam hal ini ia hanya melakukan hal itu dan keluar.
Anda tidak dapat melakukannya dengan "utas" / "proses".
Linus