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

Pengantar Sistem Operasi


Halo, Habr! Saya ingin menarik perhatian Anda serangkaian artikel-terjemahan dari satu literatur yang menarik menurut saya - OSTEP. Artikel ini membahas lebih dalam karya sistem operasi mirip-unix, yaitu, bekerja dengan proses, berbagai penjadwal, memori, dan komponen serupa lainnya yang membentuk OS modern. Asli semua bahan bisa Anda lihat di sini . Harap dicatat bahwa terjemahannya dilakukan secara tidak profesional (cukup bebas), tetapi saya harap saya tetap memiliki makna umum.

Pekerjaan laboratorium tentang hal ini dapat ditemukan di sini:


Bagian lain:


Dan Anda dapat melihat saluran saya di telegram =)

Alarm! Ada laboratorium untuk kuliah ini! menonton github

API proses



Pertimbangkan contoh membuat proses pada sistem UNIX. Ini terjadi melalui dua system call fork () dan exec () .

Panggilan Fork ()


gambar

Pertimbangkan program yang melakukan panggilan fork (). Hasil implementasinya adalah sebagai berikut.

gambar

Pertama-tama, kita memasuki fungsi utama () dan menjalankan output dari string ke layar. String berisi pengenal proses, yang dalam aslinya disebut PID atau pengidentifikasi proses. Identifier ini digunakan pada UNIX untuk merujuk pada suatu proses. Perintah selanjutnya akan memanggil fork (). Pada titik ini, salinan proses yang hampir pasti dibuat. Untuk OS, sepertinya sistem berjalan seolah-olah 2 salinan dari program yang sama, yang pada gilirannya akan keluar dari fungsi fork (). Proses anak yang baru dibuat (relatif terhadap proses induk yang membuatnya) tidak akan lagi dijalankan, dimulai dengan fungsi main (). Harus diingat bahwa proses anak bukanlah salinan persis dari proses induk, khususnya, ia memiliki ruang alamat sendiri, register sendiri, penunjuk sendiri untuk 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 akan menerima nilai yang sama dengan 0. Berdasarkan kode pengembalian ini, sudah dimungkinkan untuk memisahkan proses dan memaksa masing-masing dari mereka untuk melakukan pekerjaan mereka. Selain itu, pelaksanaan program ini tidak sepenuhnya ditentukan. Setelah membagi menjadi 2 proses, OS mulai mengikuti mereka, juga, dan merencanakan pekerjaan mereka. Jika dijalankan pada prosesor single-core, salah satu proses akan terus bekerja, dalam hal ini, orang tua, dan kemudian proses anak akan menerima kontrol. Ketika Anda memulai ulang, situasinya mungkin berbeda.

Panggilan tunggu ()


gambar

Pertimbangkan program berikut. Dalam program ini, karena kehadiran panggilan tunggu () , proses induk akan selalu menunggu proses anak untuk menyelesaikan pekerjaannya. Dalam hal ini, kami mendapatkan output teks yang didefinisikan dengan ketat ke layar.

gambar

Panggil eksekutif ()


gambar

Pertimbangkan panggilan ke exec () . Panggilan sistem ini berguna ketika kita ingin menjalankan program yang sama sekali berbeda. Di sini kita akan memanggil execvp () untuk menjalankan program wc, yang merupakan program penghitungan kata. Apa yang terjadi ketika exec () dipanggil? Nama file yang dapat dieksekusi dan beberapa parameter diteruskan ke panggilan ini sebagai argumen. Setelah itu, kode dan data statis dari file yang dapat dieksekusi ini diunduh dan segmennya sendiri dengan kode ditimpa. Bagian memori yang tersisa, seperti tumpukan dan tumpukan, diinisialisasi ulang. Setelah itu OS hanya menjalankan program, melewatinya serangkaian argumen. Jadi, kami tidak membuat proses baru, kami hanya mengubah program yang sedang berjalan menjadi program yang berjalan lainnya. Setelah exec () dieksekusi, turunan memberi kesan bahwa program aslinya sepertinya tidak dimulai secara prinsip.

Komplikasi peluncuran ini benar-benar normal untuk shell Unix, dan memungkinkan shell ini untuk mengeksekusi kode setelah memanggil fork () , tetapi sebelum memanggil exec () . Contoh dari kode tersebut dapat menyesuaikan lingkungan shell dengan kebutuhan program yang diluncurkan, sebelum meluncurkannya secara langsung.

Shell hanyalah program pengguna. Dia menunjukkan kepada Anda baris prompt dan menunggu Anda untuk menulis sesuatu untuk itu. Dalam kebanyakan kasus, jika Anda menulis nama program di sana, shell akan menemukan lokasinya, memanggil metode fork (), dan kemudian, untuk membuat proses baru, ia akan memanggil beberapa jenis exec () dan menunggu untuk dieksekusi menggunakan panggilan wait (). Ketika proses anak berakhir, shell kembali dari panggilan wait () dan menampilkan prompt lagi dan menunggu perintah selanjutnya dimasukkan.

Memisahkan garpu () & exec () memungkinkan shell untuk melakukan hal-hal berikut, misalnya:
file wc> new_file.

Dalam contoh ini, output dari wc diarahkan ke file. Cara shell mencapai ini cukup sederhana - saat membuat proses anak sebelum memanggil exec () , shell menutup aliran output standar dan membuka file new_file , sehingga semua output dari program wc yang dijalankan akan diarahkan ke file alih-alih layar.

Pipa unix diimplementasikan dengan cara yang sama, dengan perbedaan bahwa mereka menggunakan panggilan pipe (). Dalam hal ini, aliran output dari proses akan terhubung ke antrian pipa yang terletak di kernel dimana aliran input dari proses lain akan dilampirkan.

Source: https://habr.com/ru/post/id447182/


All Articles