2012-03-15 19 views
5

i "Çatal()", yaşadığım, iki farklı süreçler olmalıdır, kod aşağıdaki çalıştırdığınızda bir çatal() akımı (çağırarak) sürecinin tam bir kopyası çağrıldığında started.Now olduğunu her yerde okumak için yeni vars ve işlevlerine atanan iki farklı bellek konumu.Çatal kullanıldığında bellek nasıl eşlenir?

#include<stdio.h> 
int i=10; 
int pid; 
int main(){ 
    if((pid=fork())==0){ 
    i++;//somewhere I read that separate memory space for child is created when write is needed 
    printf("parent address= %p\n",&i);// this should return the address from parent's memory space 
    }else{ 
    i++; 
    i++; 
    printf("child address= %p\n",&i);// this should return the address of child's memory space 
    } 
    wait(0); 
    return(0); 
} 
 
Why The output looks like:: 
child address::804a01c 
parent address::804a01c 

Neden hem adres ebeveyn hem de çocuk için aynıdır?

+4

Onlar daha iyiydi * aynı olmalılar. İşaretçilerin bellekleri her iki işlemde de aynı şekilde göndermelerini istiyorsunuz (her iki bellek parçası da farklı olsa bile). Oku * sanal bellek *, bu sorunuza cevap verecektir. –

+1

Her iki kopya da aynı sanal adreste depolanmış olsa bile, 'i'nin * değerlerinin * ebeveyn ve çocuk arasında farklı olduğunu unutmayın. – markgz

cevap

8

onların vars ve fonksiyonlara atanan iki farklı bellek konumlarını sahip.

Nope; Linux, virtual memory'u uygular, bu da her işlemin kendi eksiksiz adres alanına sahip olduğu anlamına gelir. Sonuç olarak, bir fork'dan sonra, her iki süreç de bellek içi nesnelerin kopyaları için aynı adresleri görür.

:

+4

"Bir kenara" aslında çok önemli: Çocuk süreci doğduğunda hiçbir şey gerçekten kopyalanmaz. Bu, Unixes'in (hemen hemen her yeni bir süreç ürettiğinizde) çok sık gerçekleştiğine göre büyük bir performans kaybı olacaktır. Kesin mekanizma "sayfa hataları" na dayanır. Eğer ilgilenirseniz, onlar hakkında okumak isteyebilirsiniz. Ben bunu yapamazsınız düşünüyorum, ama uzmanlar onaylamak izin verir:? –

+0

Tamam, öyleyse nasıl – buch11

+1

buch11 @ (merakımı gidermek için sadece soruyorum) biz gerçek olduğunu var adresini ve sanal bir olsun alabilirsiniz. Her neyse, yapmamalısın. Bu tür bir bilgi sadece çekirdek tarafından bilinir ve yalnızca süreç yerel adreslerine erişmenize izin verir. Bu "korunan hafıza" olarak bilinir. Her işlem sadece kendi belleğine erişebilir. –

2

Adresler işlem yerel (bir kenara VM da kod fiziksel bellekte işlemi arasında paylaşılmasına neden olur ve tüm veriler sadece copied-on-write olacaktır.). Bir işlemde 804a01c, başka bir işlemde 804a01c ile aynı değildir. Çünkü virtual memory arasında

2

: Her iki adres alanı, ilgili işlemlere benzer bir nokta. Depolanan fiziksel hafıza farklıdır. Bununla birlikte, pratikte, bir bellek optimizasyonu (çoğu çekirdek tarafından uygulanan) ile ilgili karmaşık sanal sayfaları aynı fiziksel sayfalarla eşleştiren, bu işlemlerden biri bu sayfa belleğine yazılana kadar fiziksel olarak ikiye ayrılır. başka bir fiziksel adrese (ve işlem için sanal sayfa yeniden eşleştirilir).

Diğer birçok sorun da vardır: En çok tanınan değer, fork() döndürme değerinin işlemler arasında farklılık göstermesidir, ancak bu genellikle bellekte değil, bir kayıt değerindeki bir farktır. Ancak, açık dosyalar ve diğer bazı kaynaklar, kalıtımsal olarak işaretlenebilir, bu nedenle — küçük ancak bazen yararlı olabilecek başka farklılıklar olabilir.

İlgili konular