Sistem Operasi: Tiga Bagian Mudah. Bagian 3: Proses API (terjemahan)

Pengantar Sistem Operasi

Hai Habr! Saya ingin menyampaikan kepada Anda serangkaian artikel-terjemahan dari salah satu literatur yang menarik menurut saya - OSTEP. Materi ini membahas cukup mendalam tentang cara kerja sistem operasi mirip unix, yaitu bekerja dengan proses, berbagai penjadwal, memori, dan komponen serupa lainnya yang membentuk sebuah OS modern. Anda dapat melihat semua materi asli di sini di sini. Harap dicatat bahwa terjemahannya dibuat tidak profesional (cukup bebas), tapi saya harap saya tetap mempertahankan arti umum.

Pekerjaan laboratorium mengenai hal ini dapat ditemukan di sini:

Bagian lain:

Anda juga dapat memeriksa saluran saya di telegram =)

Alarm! Ada laboratorium untuk kuliah ini! Lihat github

API Proses

Mari kita lihat contoh pembuatan proses dalam sistem UNIX. Itu terjadi melalui dua panggilan sistem garpu() ΠΈ exec ().

Garpu panggilan()

Sistem Operasi: Tiga Bagian Mudah. Bagian 3: Proses API (terjemahan)

Pertimbangkan sebuah program yang membuat panggilan fork(). Hasil pelaksanaannya adalah sebagai berikut.

Sistem Operasi: Tiga Bagian Mudah. Bagian 3: Proses API (terjemahan)

Pertama-tama, kita masuk ke fungsi main() dan mencetak string ke layar. Baris tersebut berisi pengidentifikasi proses yang dalam bahasa aslinya disebut PID atau pengenal proses. Pengidentifikasi ini digunakan di UNIX untuk merujuk ke suatu proses. Perintah selanjutnya akan memanggil fork(). Pada titik ini, salinan proses yang hampir sama persis dibuat. Untuk OS, sepertinya ada 2 salinan program yang sama yang berjalan di sistem, yang selanjutnya akan keluar dari fungsi fork(). Proses anak yang baru dibuat (sehubungan dengan proses induk yang membuatnya) tidak akan lagi dieksekusi, dimulai dari fungsi main(). Harus diingat bahwa proses anak bukanlah salinan persis dari proses induk; khususnya, ia mempunyai ruang alamatnya sendiri, registernya sendiri, penunjuknya sendiri ke instruksi yang dapat dieksekusi, dan sejenisnya. Dengan demikian, nilai yang dikembalikan ke pemanggil fungsi fork() akan berbeda. Secara khusus, proses induk akan menerima nilai PID dari proses anak sebagai pengembalian, dan anak tersebut akan menerima nilai yang sama dengan 0. Dengan menggunakan kode pengembalian ini, Anda kemudian dapat memisahkan proses dan memaksa masing-masing proses untuk melakukan tugasnya sendiri. . Namun, pelaksanaan program ini tidak didefinisikan secara ketat. Setelah dibagi menjadi 2 proses, OS mulai memantaunya, serta merencanakan pekerjaannya. Jika dijalankan pada prosesor inti tunggal, salah satu proses, dalam hal ini proses induk, akan terus bekerja, dan kemudian proses anak akan menerima kendali. Saat memulai ulang, situasinya mungkin berbeda.

Panggilan tunggu()

Sistem Operasi: Tiga Bagian Mudah. Bagian 3: Proses API (terjemahan)

Perhatikan program berikut ini. Dalam program ini, karena adanya panggilan tunggu() Proses induk akan selalu menunggu hingga proses anak selesai. Dalam hal ini, kita akan mendapatkan keluaran teks yang ditentukan secara ketat di layar

Sistem Operasi: Tiga Bagian Mudah. Bagian 3: Proses API (terjemahan)

exec() panggilan

Sistem Operasi: Tiga Bagian Mudah. Bagian 3: Proses API (terjemahan)

Pertimbangkan tantangannya exec (). System call ini berguna ketika kita ingin menjalankan program yang benar-benar berbeda. Di sini kami akan menelepon eksekutif() untuk menjalankan program wc yang merupakan program penghitungan kata. Apa yang terjadi ketika exec() dipanggil? Panggilan ini meneruskan nama file yang dapat dieksekusi dan beberapa parameter sebagai argumen. Setelah itu kode dan data statis dari file yang dapat dieksekusi ini dimuat dan segmennya sendiri dengan kode tersebut ditimpa. Area memori yang tersisa, seperti tumpukan dan heap, diinisialisasi ulang. Setelah itu OS hanya mengeksekusi program tersebut, meneruskan serangkaian argumen. Jadi kami tidak membuat proses baru, kami hanya mengubah program yang sedang berjalan menjadi program lain yang sedang berjalan. Setelah menjalankan panggilan exec() di turunannya, tampaknya program aslinya tidak berjalan sama sekali.

Komplikasi startup ini sepenuhnya normal untuk shell Unix, dan memungkinkan shell tersebut mengeksekusi kode setelah dipanggil garpu(), tapi sebelum panggilan exec (). Contoh kode tersebut adalah menyesuaikan lingkungan shell dengan kebutuhan program yang diluncurkan, sebelum meluncurkannya.

Kulit - hanya program pengguna. Dia menunjukkan baris undangan dan menunggu Anda menulis sesuatu di dalamnya. Dalam kebanyakan kasus, jika Anda menulis nama program di sana, shell akan menemukan lokasinya, memanggil metode fork(), dan kemudian memanggil beberapa jenis exec() untuk membuat proses baru dan menunggu hingga selesai menggunakan a tunggu() panggilan. Ketika proses anak keluar, shell akan kembali dari panggilan wait() dan mencetak prompt lagi dan menunggu perintah selanjutnya dimasukkan.

Perpecahan fork() & exec() memungkinkan shell melakukan hal-hal berikut, misalnya:
file wc > file_baru.

Dalam contoh ini, output dari program wc dialihkan ke sebuah file. Cara shell mencapai hal ini cukup sederhana - dengan membuat proses anak sebelum memanggil exec (), shell menutup keluaran standar dan membuka file file baru, dengan demikian, semua keluaran dari program yang berjalan selanjutnya wc akan dialihkan ke file, bukan ke layar.

pipa Unix diimplementasikan dengan cara yang sama, dengan perbedaan bahwa mereka menggunakan panggilan pipe(). Dalam hal ini, aliran keluaran proses akan dihubungkan ke antrian pipa yang terletak di kernel, dimana aliran masukan dari proses lain akan dihubungkan.

Sumber: www.habr.com

Tambah komentar