2010-03-07 28 views
6

Çatal hakkında okudum ve anladığım kadarıyla süreç klonlandı ama hangi süreç? Senaryonun kendisi veya senaryoyu başlatan süreç? ÖrneğinBir işlem çatallandığında ne olur?

:

benim makinede rtorrent çalıştırıyorum ve bir sel tamamlandığında, bir komut dosyası buna karşı çalıştırmak. Bu komut, web'den veri alır, böylece tamamlanması birkaç saniye sürer. Bu süre zarfında, rüşvet sürecim donmuş durumda. ben amaçlanan tam olarak arka planda çalışır iken Ben de CLI bu komut dosyasını çalıştırırsanız aşağıdaki

my $pid = fork(); 
if ($pid == 0) { blah blah blah; exit 0; } 

kullanarak komut çatal yapılmış, bir saniye içinde geri kabuk gelir. Ancak, rTorrent’ten çalıştırdığımda, eskisinden daha da yavaş görünüyor. Yani tam olarak ne çatal olmuştu? Rtorrent süreci kendini klonladı ve benim betiğimde mi çalıştı, yoksa senaryonun kendisi mi klonlandı? Umarım bu mantıklı gelir.

+1

Lütfen bir çalışan perl snippet'i yayınlayarak başlayın. –

+2

strace'de rTorrent çalıştırmayı deneyin ve komut dosyanız çalışırken ne engellendiğini görün. Bu bir ipucu verebilir. Torun süreci üzerinde beklemiş olabileceğini düşünüyordum, fakat geleneksel sistem çağrılarını kullanarak davranışın aslında mümkün olmadığı anlaşılıyor. – jdizzle

cevap

2

Nominal soruya cevap vermek için, kabul edilen yanıtın başarısız olduğunu belirttiğiniz için, fork, çağrıldığı işlemi etkiler.Daha sonra fork olarak adlandırılan bir Perl işlemi rtorrent yumurtlama örneğinizde, bu, fork olarak adlandırılan Perl işlem olduğundan çoğaltılan Perl işlemidir. Genel durumda, bir işlemin kendisinden başka herhangi bir işlem için fork yolunun bir yolu bulunmamaktadır. Başka bir rasgele sürecin kendisine fork gitmesini söylemek mümkün olsaydı, bu güvenlik ve performans sorunlarının bir sonu olmazdı.

+2

Birçok şaka olasılığını ortaya çıkarmanın yanı sıra: "hey sen! "hayır, çatal!" – Ether

6

fork() işlevi, TWICE! Ebeveyn sürecinde ve bir kez çocuk süreçte. Genel olarak, her iki süreç de, her biri fork()'dan geri döndü. Tek fark, bir, fork() gelen dönüş değeri 0 ve diğeri sıfır olmayan (alt işlemin PID) olmasıdır.

Yani ne olursa olsun süreç (o rtorrent içine gömülü bir Perl yorumlayıcısı ise o zaman rtorrent süreç olacağını) Perl komut dosyası koşuyordu fork() oldu ki tam noktada çoğaltılamaz olacaktır.

+0

Bunun gerçekten onun sorusu olduğunu sanmıyorum ... – jdizzle

+2

@jdizzle - Muhtemelen soru çok anlamlı olmadığı için, çünkü 'kimse' süreci ve fikirleri anlamaz. Bazı gerçekleri açıklamak yardımcı olabilir :) – viraptor

+1

@viraptor - Birinin yeterince iyi bir çatal() kavraması olduğunu hissediyorum. Soru, rTorrent'in uygulanması hakkında gerçekten. – jdizzle

3

Tercüman çatallarını içeren tüm süreç. Neyse ki, bellek yazma üzerine yazılır, böylece tüm işlem belleğini kopyalamak için kopyalamaya gerek yoktur. Ancak, dosya tanıtıcıları gibi şeyler açık kalır. Bu, çocuk süreçlerinin bunları işlemesine izin verir, ancak uygun şekilde kapatılmadığında sorunlara neden olabilir. Genelde, fork() aşırı zorlama dışında gömülü bir yorumlayıcıda kullanılmamalıdır.

+0

Meh. Dünyanın sonu, son kullanıcının makinesinde perl'de fork(). Sık sık kullanılması (muhtemelen bir darboğaz için olgun bir nokta olduğu gibi) kötü bir uygulama olduğunu kabul ediyorum. – jdizzle

+0

Eğer bu kötü bir uygulamasa, engellemeyi önlemek için alternatif bir yöntem var mı? – somebody

2

Tavsiyem "bunu yapma" olur.

Perl yorumlayıcısı, rtorrent süreci içine gömülmüşse, hemen hemen kesinlikle en iyi ihtimalle kötü tanımlanmış olan tüm bir rtorrent sürecini tamamlamanız mümkün. Genelde dilden bağımsız olarak gömülü bir yorumlayıcıda işlem seviyesinde şeyler oynamak kötü bir fikirdir.

Bazı tür kilitlerin düzgün bir şekilde serbest bırakılmadığı ya da süreçlerdeki iş parçacıklarının istenmeyen ve muhtemelen rakip yollarla ilerlemesinin mükemmel bir şansı vardır.

+0

Perl yorumlayıcısına karşı gerçekte bağlantı kurmak ne kadar yaygın? Bu tür çağrılara sistem() için daha pratik (ve güvenli) olmaz mıydı? – jdizzle

+0

Çok parçalı bir programda fork() 'sözcüğünü çağırmanın sorun olduğunu doğrular. Çocuk işleminde ne olduğunu kısıtlarsanız, o kadar da kötü değil. Örneğin, kullanıcı modu kilidini alması gereken hiçbir şeyi arama. Fakat 'fork()' 'dup2()' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'tipik kullanım aşağıdaki gibi olmalıdır. – asveikau

+0

@jdizzle: Harici bir tercümana, Perl'e veya başka bir şeye bağ kurmak çok yaygındır, ancak bu programın durumunun olup olmadığı sorusu tamamen açık değildir. Yine de yeniden okumada, sistem() kullanılmakta doğru olabilirsiniz. –

4

Sorunu rTorrent kaynağına bakarak bulacağımı düşünüyorum. Bazı işlemler için, devam etmeden önce stdout'a gönderilen tüm çıktıları okuyacaktır. Bu işleminize devam ederse, rTorrent stdout işlemini kapatıncaya kadar engellenir. Çünkü sen özelsin, çocuk sürecin ebeveynle aynı stdoutu paylaşır. Ebeveyn süreciniz çıkacak, ancak boru açık kalacaktır (çünkü çocuk işleminiz hala devam ediyor). Eğer bir rTorrent strace yaptıysanız, bu komutun yürütülmesi sırasında bu read() numaralı çağrıda engelleneceğine bahse girerim.

Stdout'u, perl betiğinize fork()'dan önce kapatmayı/yeniden yönlendirmeyi deneyin.

+0

Sorunu çözer, ancak nominal soruyu yanıtlamaz. Bunu isterim. – darch

+0

@darch - sorunun başlığı aslında birisinin – jdizzle

+0

çözmeye çalıştığı problemle ilgilidir. Bu çok yararlı olduğunu buldum, bu yüzden "nominal soruyu yanıtlamadı" diye eklediğiniz için teşekkürler, @jdizzle :) –

1

Çatal kullanarak bir işlem oluşturduğumuzda, alt işlemin adres alanının kopyasına sahip olur. Çocuğun adres alanını da kullanabilir. Ayrıca ebeveyn tarafından açılan dosyalara da erişebilir. Çocuğun kontrolü. Çocuğun tam durumunu elde etmek için bekleyebiliriz.

İlgili konular