Yerleşik komutlar ne zaman belleğe yüklenir


11

Diyelim ki cdkabuğuma yazarsam. Is cdo anda bellekten yüklenen? Sezgim, bu yerleşik komutların çekirdek yüklendikten sonra sistem belleğine önceden yüklenmesidir, ancak birisi yalnızca komutu gerçekten başlattığımda (bir kabukta enter tuşuna bastığımda) yüklenmeleri konusunda ısrar etti. Bunu açıklayan bir referans olup olmadığını söyleyebilir misiniz?


1
Bence bu cevap , yinelenen bir bilgi olmasa da anlamanıza yardımcı olacaktır.
cjm

@cjm: Teşekkürler gerçekten okumak için iyi bir açıklama oldu.
Forethinker

Yanıtlar:


9

Diyelim ki kabuğuma cd yazarsam. O anda cd bellekten yüklenmiş mi? Sezgim, bu yerleşik komutların çekirdek yüklendikten sonra sistem belleğine önceden yüklenmesidir, ancak birisi yalnızca komutu gerçekten çağırdığımda yüklendiğinde ısrar etti ...

Geniş anlamda diğer cevaplar doğrudur - yerleşikler kabukla yüklenir, çağrıldığında stand-alonlar yüklenir. Ancak, çok cesur bir gelincik-y "birisi" bu kadar basit olmadığını ısrar edebilir.

Bu tartışma, işletim sisteminin nasıl çalıştığı ve farklı işletim sistemlerinin farklı şekillerde nasıl çalıştığıyla ilgilidir, ancak genel olarak aşağıdakilerin muhtemelen tüm çağdaş * nixes için doğru olduğunu düşünüyorum.

İlk olarak, "belleğe yüklendi" belirsiz bir ifadedir; gerçekten bahsettiğimiz şey sanal adres alanının belleğe eşlenmesi . "Sanal adres alanı" belleğe yerleştirilmesi gerekebilecek şeyler anlamına gelir, ancak aslında başlangıçta değildir: çoğunlukla belleğe yüklenen şey haritanın kendisidir - ve harita bölge değildir. "Bölge" aslında, yürütülebilir diskte (ya da önbellek olarak) ve olacağını, bunun büyük olasılıkla olduğu değil sizi bir yürütülebilir çağırmak belleğe yüklenir.

Ayrıca, "bölge" nin çoğu diğer bölgelere (paylaşılan kütüphaneler) yapılan göndermelerdir ve yine, sadece sevk edildikleri için gerçekten de yüklendikleri anlamına gelmez. Onlar gerçekten kullanılıncaya kadar yüklenmezler ve daha sonra sadece "kullanım" ın başarılı olması için yüklenmeleri gereken parçaları.

Örneğin, toplinux'da bir bashörneğe gönderme yapan bir çıktı snippet'i :

VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                  
113m 3672 1796 S  0.0  0.1   0:00.07 bash   

113 MB VIRT, RAM'de eşlenen sanal adres alanıdır . Ancak RES, işlem tarafından kullanılan gerçek RAM miktarıdır - sadece 3,7 kB. Ve bazıları, yukarıda belirtilen paylaşılan bölgenin bir parçası - 1.8 kB SHR. Ama benim /bin/bashdiskim 930 kB, ve (paylaşılan bir lib) bağlanan temel libc tekrar iki kat daha büyük.

Şu kabuk hiçbir şey yapmıyor. Diyelim ki, daha önce kabuğun geri kalanıyla birlikte zaten "belleğe yüklendi" dediğimiz yerleşik bir komutu çağırıyorum. Çekirdek, haritadaki bir noktadan başlayarak dahil edilen kodu çalıştırır ve gerçekten yüklenmemiş bir kod referansına ulaştığında, daha rahat olmasına rağmen - diskteki yürütülebilir bir görüntüden - yükler yani, çalıştırılabilir dosya (kabuk, tek başına bir araç veya paylaşılan bir kütüphane olsun) zaten "belleğe yüklenmiş".

Buna talep çağrısı denir .


9

Ağır ağırlıklardan birinin gelmesini ve tam bir tarihsel perspektif beklemesini sağlarken, size daha sınırlı anlayışımı vereceğim.

Dahili gibi komutları alias, cd, echovb kabuğundan parçası olan ( bash, zsh, kshya da her neyse). Kabuk aynı zamanda yüklenir ve sadece kabuğun iç işlevleridir.


4

Yerleşik komutların aslında exectuable'ın bir parçası olarak yüklendiğini göstermek için aşağıdaki deneyi yaptım bash. Bu yüzden neden yerleşik olarak adlandırılırlar, ancak bir demo her zaman bir şeyi kanıtlamanın en iyi yoludur.

Misal

  1. Yeni bir bashkabuk başlatın ve işlem kimliğini (PID) not edin:

    $ bash
    $ echo $$
    6402
    
  2. İkinci bir terminalde, ek bellek almaya başlayıp başlamadığını psizlemek ve görmek için komutu çalıştırın bash:

    $ watch "ps -Fp 6402"
    

    Çıktı şöyle görünür:

    Every 2.0s: ps -Fp 6402                        Sat Sep 14 14:40:49 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml      6402  6349  0 28747  6380   1 14:33 pts/38   00:00:00 bash
    

    NOT: Bellek kullanımı burada SZ ve RSS sütunlarıyla gösterilir.

  3. Kabuktaki komutları çalıştırmaya başlayın (pid 6402):

    Eğer gibi cdetrafında aslında yukarı gidiyor hafızayı fark edersiniz; ancak bu, çünkü çalıştırılabilir ait değildir cdbelleğe yüklenir varlık diskte dizin yapısı belleğe yüklenir oluyor, çünkü oldukça budur. Eğer cddiğer dizinlere devam ederseniz, onun sürekli arttığını göreceksiniz.

    Every 2.0s: ps -Fp 30208                        Sat Sep 14 15:11:22 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml     30208  6349  0 28780  6492   0 15:09 pts/38   00:00:00 bash
    

    Bunun gibi daha ayrıntılı testler yapabilirsiniz:

    $ for i in `seq 1000`; do cd ..; cd 90609;done
    

    Bu komut bir düzey yukarı cd ve daha sonra 90609 dizinine 1000 kez geri. psPenceredeki bellek kullanımını izlerseniz, bunu çalıştırırken değişmediğini fark edeceksiniz. Böyle bir şey çalıştırırken, ek bellek kullanımı fark edilmemelidir.

  4. strace

    İşte bashgerçek bir yürütülebilir dosya yerine yerleşik bir işlevle uğraştığımızı başka bir anlatmak . Çalıştırmaya çalıştığınızda strace cd ..aşağıdaki mesajı alırsınız:

    $ strace cd ..
    strace: cd: command not found
    

3

"yerleşik komut" ayrı programlar olarak değil, kabuğun içine yerleştirilmiş komutları ifade eder. lsörneğin, aslında yerleşik bir komut değil, ayrı bir programdır. Disk önbelleğinde olmadığı sürece, çağrıldığında RAM'e yüklenecektir.

Yerleşik komutun bir örneği printfveya olabilir cd. Bunlar kabuğun bir parçasıdır ve kabuğun geri kalanıyla birlikte yüklenir.

Sistemler bunu yapmak için oluşturulmuş olsa da, varsayılan olarak hiçbir komut önceden yüklenmez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.