İşletim Sistemleri: Üç Kolay Parça. Bölüm 3: İşlem API'si (çeviri)

İşletim Sistemlerine Giriş

Ey Habr! Bence ilginç bir literatür olan OSTEP'in bir dizi makale-çevirisini dikkatinize sunmak istiyorum. Bu materyal, unix benzeri işletim sistemlerinin çalışmasını, yani modern bir işletim sistemini oluşturan süreçler, çeşitli zamanlayıcılar, bellek ve diğer benzer bileşenlerle çalışmayı oldukça derinlemesine tartışıyor. Tüm malzemelerin orijinalini burada görebilirsiniz burada. Lütfen çevirinin profesyonelce yapılmadığını (oldukça özgürce) unutmayın, ancak umarım genel anlamı korumuşumdur.

Bu konudaki laboratuvar çalışmasına buradan ulaşabilirsiniz:

Diğer parçalar:

kanalıma da bakabilirsin telgraf =)

Alarm! Bu ders için bir laboratuvar var! Bakmak github

İşlem API'si

UNIX sisteminde bir süreç oluşturmaya ilişkin bir örneğe bakalım. İki sistem çağrısı aracılığıyla gerçekleşir çatal() и yürüt().

Çağrı çatalı()

İşletim Sistemleri: Üç Kolay Parça. Bölüm 3: İşlem API'si (çeviri)

fork() çağrısı yapan bir program düşünün. Yürütülmesinin sonucu aşağıdaki gibi olacaktır.

İşletim Sistemleri: Üç Kolay Parça. Bölüm 3: İşlem API'si (çeviri)

Öncelikle main() fonksiyonuna girip stringi ekrana yazdırıyoruz. Satır, orijinalde adı verilen işlem tanımlayıcıyı içerir. PID veya süreç tanımlayıcı. Bu tanımlayıcı UNIX'te bir sürece atıfta bulunmak için kullanılır. Bir sonraki komut fork()'u çağıracaktır. Bu noktada sürecin neredeyse birebir kopyası oluşturulur. İşletim sistemi için, sistemde çalışan aynı programın 2 kopyası var gibi görünüyor ve bu da fork() işlevinden çıkacak. Yeni oluşturulan alt süreç (kendisini oluşturan ana süreçle ilişkili olarak), main() işlevinden başlayarak artık yürütülmeyecektir. Bir alt sürecin ana sürecin tam bir kopyası olmadığı unutulmamalıdır; özellikle kendi adres alanına, kendi kayıtlarına, çalıştırılabilir talimatlara yönelik kendi işaretçisine ve benzerlerine sahiptir. Bu nedenle fork() fonksiyonunun çağırıcısına döndürülen değer farklı olacaktır. Özellikle ana süreç, alt sürecin PID değerini dönüş olarak alacak ve alt süreç 0'a eşit bir değer alacaktır. Bu dönüş kodlarını kullanarak daha sonra süreçleri ayırabilir ve her birini kendi işini yapmaya zorlayabilirsiniz. . Ancak bu programın yürütülmesi kesin olarak tanımlanmamıştır. İşletim sistemi 2 sürece bölündükten sonra bunları izlemeye ve çalışmalarını planlamaya başlar. Tek çekirdekli bir işlemcide yürütülürse, süreçlerden biri (bu durumda ana süreç) çalışmaya devam edecek ve ardından alt süreç kontrolü ele alacaktır. Yeniden başlatırken durum farklı olabilir.

Çağrı bekle()

İşletim Sistemleri: Üç Kolay Parça. Bölüm 3: İşlem API'si (çeviri)

Aşağıdaki programı düşünün. Bu programda bir çağrının varlığı nedeniyle Bekle() Ana süreç her zaman alt sürecin tamamlanmasını bekleyecektir. Bu durumda ekranda kesin olarak tanımlanmış bir metin çıktısı alacağız.

İşletim Sistemleri: Üç Kolay Parça. Bölüm 3: İşlem API'si (çeviri)

exec() çağrısı

İşletim Sistemleri: Üç Kolay Parça. Bölüm 3: İşlem API'si (çeviri)

Mücadeleyi düşünün yürüt(). Bu sistem çağrısı tamamen farklı bir program çalıştırmak istediğimizde kullanışlıdır. İşte arayacağız execvp() Kelime sayma programı olan wc programını çalıştırmak için. exec() çağrıldığında ne olur? Bu çağrıya yürütülebilir dosyanın adı ve bazı parametreler bağımsız değişken olarak iletilir. Bundan sonra bu yürütülebilir dosyadaki kod ve statik veriler yüklenir ve kodun bulunduğu kendi bölümünün üzerine yazılır. Yığın ve yığın gibi kalan bellek alanları yeniden başlatılır. Bundan sonra işletim sistemi programı çalıştırır ve ona bir dizi argüman iletir. Yani yeni bir süreç yaratmadık, sadece şu anda çalışan programı çalışan başka bir programa dönüştürdük. Alt öğedeki exec() çağrısını yürüttükten sonra, sanki orijinal program hiç çalışmıyormuş gibi görünüyor.

Bu başlatma komplikasyonu bir Unix kabuğu için tamamen normaldir ve kabuğun çağrıldıktan sonra kod yürütmesine izin verir. çatal(), ancak aramadan önce yürüt(). Böyle bir kodun bir örneği, kabuk ortamını, başlatılan programın ihtiyaçlarına göre, onu başlatmadan önce ayarlamak olabilir.

Kabuk - sadece bir kullanıcı programı. Size davetiye satırını gösteriyor ve içine bir şeyler yazmanızı bekliyor. Çoğu durumda, buraya bir programın adını yazarsanız, kabuk konumunu bulur, fork() yöntemini çağırır ve ardından yeni bir işlem oluşturmak için bir tür exec() çağırır ve bir işlem kullanarak tamamlanmasını bekler. wait() çağrısı. Alt işlemden çıkıldığında, kabuk wait() çağrısından geri dönecek ve istemi tekrar yazdıracak ve bir sonraki komutun girilmesini bekleyecektir.

fork() ve exec() ayrımı, kabuğun aşağıdakileri yapmasına olanak tanır, örneğin:
wc dosyası > new_file.php

Bu örnekte wc programının çıktısı bir dosyaya yönlendirilmektedir. Kabuğun bunu başarma yolu oldukça basittir; çağırmadan önce bir alt süreç oluşturarak yürüt()kabuk standart çıktıyı kapatır ve dosyayı açar yeni dosya, böylece daha sonra çalışan programın tüm çıktıları wc ekran yerine bir dosyaya yönlendirilecektir.

Unix borusu pipe() çağrısı kullanmaları farkıyla benzer şekilde uygulanır. Bu durumda, sürecin çıkış akışı, başka bir sürecin giriş akışının bağlanacağı çekirdekte bulunan bir boru kuyruğuna bağlanacaktır.

Kaynak: habr.com

Yorum ekle