Sistem Pengendalian: Tiga Keping Mudah. Bahagian 3: API Proses (terjemahan)

Pengenalan kepada Sistem Operasi

Hai Habr! Saya ingin membawa perhatian anda satu siri artikel-terjemahan satu kesusasteraan yang menarik pada pendapat saya - OSTEP. Bahan ini membincangkan secara mendalam tentang kerja sistem pengendalian seperti unix, iaitu, bekerja dengan proses, pelbagai penjadual, memori, dan komponen lain yang serupa yang membentuk OS moden. Anda boleh melihat asal semua bahan di sini di sini. Sila ambil perhatian bahawa terjemahan itu dibuat secara tidak profesional (agak bebas), tetapi saya harap saya mengekalkan maksud umum.

Kerja makmal mengenai subjek ini boleh didapati di sini:

Bahagian lain:

Anda juga boleh menyemak saluran saya di telegram =)

Penggera! Terdapat makmal untuk kuliah ini! Tengok github

API Proses

Mari kita lihat contoh mencipta proses dalam sistem UNIX. Ia berlaku melalui dua panggilan sistem garpu () ΠΈ exec ().

Panggilan garpu()

Sistem Pengendalian: Tiga Keping Mudah. Bahagian 3: API Proses (terjemahan)

Pertimbangkan program yang membuat panggilan fork(). Keputusan pelaksanaannya adalah seperti berikut.

Sistem Pengendalian: Tiga Keping Mudah. Bahagian 3: API Proses (terjemahan)

Pertama sekali, kami memasukkan fungsi main() dan mencetak rentetan ke skrin. Baris tersebut mengandungi pengecam proses yang dalam asalnya dipanggil PID atau pengecam proses. Pengecam ini digunakan dalam UNIX untuk merujuk kepada proses. Perintah seterusnya akan memanggil fork(). Pada ketika ini, salinan proses yang hampir tepat dibuat. Untuk OS, nampaknya terdapat 2 salinan program yang sama berjalan pada sistem, yang seterusnya akan keluar dari fungsi fork(). Proses anak yang baru dibuat (berkaitan dengan proses induk yang menciptanya) tidak akan dilaksanakan lagi, bermula dari fungsi main(). Perlu diingat bahawa proses anak bukanlah salinan tepat proses induk; khususnya, ia mempunyai ruang alamatnya sendiri, daftarnya sendiri, penunjuknya sendiri kepada arahan boleh laku, dan seumpamanya. Oleh itu, nilai yang dikembalikan kepada pemanggil fungsi fork() akan berbeza. Khususnya, proses induk akan menerima nilai PID proses anak sebagai pulangan dan anak akan menerima nilai yang sama dengan 0. Dengan menggunakan kod pulangan ini, anda kemudian boleh memisahkan proses dan memaksa setiap daripada mereka melakukan kerjanya sendiri . Walau bagaimanapun, pelaksanaan program ini tidak ditakrifkan secara ketat. Selepas membahagikan kepada 2 proses, OS mula memantau mereka, serta merancang kerja mereka. Jika dilaksanakan pada pemproses teras tunggal, salah satu proses, dalam kes ini ibu bapa, akan terus berfungsi, dan kemudian proses anak akan menerima kawalan. Apabila dimulakan semula, keadaan mungkin berbeza.

Panggil tunggu()

Sistem Pengendalian: Tiga Keping Mudah. Bahagian 3: API Proses (terjemahan)

Pertimbangkan program berikut. Dalam program ini, kerana adanya panggilan tunggu () Proses induk akan sentiasa menunggu proses anak selesai. Dalam kes ini, kami akan mendapat output teks yang ditetapkan dengan ketat pada skrin

Sistem Pengendalian: Tiga Keping Mudah. Bahagian 3: API Proses (terjemahan)

exec() panggilan

Sistem Pengendalian: Tiga Keping Mudah. Bahagian 3: API Proses (terjemahan)

Pertimbangkan cabarannya exec (). Panggilan sistem ini berguna apabila kita ingin menjalankan program yang sama sekali berbeza. Di sini kami akan memanggil execvp() untuk menjalankan program wc iaitu program mengira perkataan. Apa yang berlaku apabila exec() dipanggil? Panggilan ini diberikan nama fail boleh laku dan beberapa parameter sebagai argumen. Selepas itu kod dan data statik daripada fail boleh laku ini dimuatkan dan segmennya sendiri dengan kod itu ditulis ganti. Kawasan memori yang tinggal, seperti timbunan dan timbunan, dimulakan semula. Selepas itu OS hanya melaksanakan program, memberikannya satu set hujah. Jadi kami tidak mencipta proses baharu, kami hanya menukar program yang sedang berjalan kepada program yang sedang berjalan. Selepas melaksanakan panggilan exec() dalam keturunan, ia kelihatan seolah-olah program asal tidak berjalan sama sekali.

Komplikasi permulaan ini benar-benar normal untuk shell Unix, dan membenarkan shell itu melaksanakan kod selepas membuat panggilan garpu (), tetapi sebelum panggilan exec (). Contoh kod sedemikian ialah melaraskan persekitaran shell kepada keperluan program yang dilancarkan, sebelum melancarkannya.

Shell - hanya program pengguna. Dia menunjukkan kepada anda baris jemputan dan menunggu anda menulis sesuatu di dalamnya. Dalam kebanyakan kes, jika anda menulis nama program di sana, shell akan mencari lokasinya, memanggil kaedah fork() dan kemudian memanggil beberapa jenis exec() untuk mencipta proses baharu dan menunggu ia selesai menggunakan a tunggu() panggil. Apabila proses kanak-kanak keluar, shell akan kembali daripada panggilan tunggu() dan mencetak gesaan sekali lagi dan menunggu arahan seterusnya dimasukkan.

Pemisahan fork() & exec() membolehkan shell melakukan perkara berikut, sebagai contoh:
fail wc > new_file.

Dalam contoh ini, output program wc dialihkan ke fail. Cara shell mencapai ini agak mudah - dengan mencipta proses anak sebelum membuat panggilan exec (), shell menutup output standard dan membuka fail fail_baru, oleh itu, semua output daripada program yang sedang berjalan wc akan diubah hala ke fail dan bukannya skrin.

Paip Unix dilaksanakan dengan cara yang sama, dengan perbezaan bahawa mereka menggunakan panggilan pipe(). Dalam kes ini, aliran keluaran proses akan disambungkan ke baris gilir paip yang terletak dalam kernel, yang mana aliran input proses lain akan disambungkan.

Sumber: www.habr.com

Tambah komen