Fork () işlevinin amacı nedir?


88

Linux'un birçok programında ve man sayfalarında kod kullanıldığını gördüm fork(). Neden kullanmamız gerekiyor fork()ve amacı nedir?


151
Böylece tüm o yemek filozofları aç kalmasın.
kenj0418

Yanıtlar:


109

fork()Unix'te yeni süreçleri nasıl yarattığınızdır. Aradığınızda fork, kendi adres alanı olan kendi işleminizin bir kopyasını oluşturuyorsunuz . Bu, birden çok görevin, her biri makinenin tam belleğine sahipmiş gibi birbirinden bağımsız olarak çalışmasına izin verir.

İşte bazı örnek kullanımlar fork:

  1. Sizin kabuk kullanır forkkomut satırından çağırmak programları çalıştırmak için.
  2. Apache gibi web sunucuları fork, her biri istekleri kendi adres alanında işleyen birden çok sunucu işlemi oluşturmak için kullanır . Biri ölürse veya bellek sızdırırsa, diğerleri etkilenmez, bu nedenle hata toleransı için bir mekanizma olarak işlev görür.
  3. Google Chrome , forkher sayfayı ayrı bir işlem içinde işlemek için kullanır . Bu, bir sayfadaki istemci tarafı kodunun tüm tarayıcınızı kapatmasını önleyecektir.
  4. forkbazı paralel programlarda ( MPI kullanılarak yazılanlar gibi) süreçleri ortaya çıkarmak için kullanılır . Bunun, kendi adres alanı olmayan ve bir işlem içinde var olan iş parçacıkları kullanmaktan farklı olduğunu unutmayın .
  5. Komut dosyası dilleri, forkalt işlemleri başlatmak için dolaylı olarak kullanır . Örneğin, subprocess.PopenPython'daki gibi bir komutu her kullandığınızda , forkbir çocuk süreç olursunuz ve çıktısını okursunuz. Bu, programların birlikte çalışmasını sağlar.

forkBir kabukta tipik kullanımı şöyle görünebilir:

Kabuk, kullanan bir çocuk süreci oluşturur execve tamamlanmasını bekler, ardından kendi yürütmesine devam eder. Bu şekilde çatal kullanmak zorunda olmadığınızı unutmayın. Paralel bir programın yapabileceği gibi her zaman çok sayıda alt süreç üretebilirsiniz ve her biri aynı anda bir programı çalıştırabilir. Temel olarak, bir Unix sisteminde yeni süreçler oluşturduğunuzda, kullanıyorsunuzdur fork(). Windows eşdeğeri için bir göz atın CreateProcess.

Daha fazla örnek ve daha uzun bir açıklama istiyorsanız, Wikipedia'nın iyi bir özeti var. İşte modern işletim sistemlerinde süreçlerin, iş parçacığının ve eşzamanlılığın nasıl çalıştığına dair bazı slaytlar burada.


Madde 5: 'sık sık' mı? Sadece 'sık' mı? Hangileri kullanmaz veya hangi koşullarda fork () kullanılmaz - fork () destekleyen sistemlerde, yani.
Jonathan Leffler

19
Garip bir şekilde, adı CreateProcess () - şu çılgın Windows adamları :-)
paxdiablo

2
"Kabuğun komut satırından çalıştırdığınız programları çalıştırmak için fork kullandığını" şimdiye kadar hiç fark etmediniz!
Lazer

1
Slaytların bağlantısı kesildi
Piertoni

1
Tüm cevaplar demek fork()UNIX içinde yeni bir süreç oluşturmak, ancak bilgiçlik olmak, diğer en az bir tane yoludur: posix_spawn().
Davislor

15

fork (), Unix'in yeni süreçler yaratmasıdır. Fork () adını verdiğiniz noktada, işleminiz klonlanır ve buradan iki farklı işlem yürütülmeye devam eder. Bunlardan biri, çocuk, fork () dönüş 0'a sahip olacaktır. Diğeri, ebeveyn, fork (), çocuğun PID'sini (süreç kimliği) döndürür.

Örneğin, bir kabuğa aşağıdakini yazarsanız, kabuk programı fork () 'u çağırır ve ardından altta geçirdiğiniz komutu (bu durumda telnetd) yürütür, üst öğe de istemi tekrar görüntüler. arka plan işleminin PID'sini belirten bir mesaj olarak.

Yeni süreçler yaratma nedeninize gelince, işletim sisteminiz aynı anda birçok şeyi bu şekilde yapabilir. Bu yüzden bir programı çalıştırabilir ve çalışırken başka bir pencereye geçip başka bir şey yapabilirsiniz.


@varDumper İyi yakalayış!
Daniel C. Sobral

9

fork (), alt süreç oluşturmak için kullanılır. Bir fork () işlevi çağrıldığında, yeni bir süreç ortaya çıkar ve fork () işlev çağrısı çocuk ve ebeveyn için farklı bir değer döndürür.

Dönüş değeri 0 ise, alt süreç olduğunuzu bilirsiniz ve dönüş değeri bir sayı ise (bu, alt süreç kimliği olur), ebeveyn olduğunuzu bilirsiniz. (ve negatif bir sayı ise, çatal başarısız oldu ve hiçbir alt süreç oluşturulmadı)

http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html


1
Dönüş değeri -1 olmadığı sürece, bu durumda fork () başarısız olur.
Jonathan Leffler

8

fork (), temelde bu işlevi çağırdığınız süreç için bir alt süreç oluşturmak için kullanılır. Bir fork () çağırdığınızda, çocuk kimliği için sıfır döndürür.

bununla ebeveyn ve çocuk için farklı eylemler sağlayabilir ve çoklu okuma özelliğini kullanabilirsiniz.


6

fork (), ebeveyn ile aynı olan yeni bir çocuk süreç yaratacaktır. Dolayısıyla, bundan sonra kodda çalıştırdığınız her şey her iki işlem tarafından da çalıştırılacaktır - örneğin bir sunucunuz varsa ve birden çok isteği işlemek istiyorsanız çok kullanışlıdır.


neden ebeveyne özdeş bir çocuk yaratıyorsun, ne faydası var?

1
Tıpkı tek bir askere karşı bir ordu kurmak gibi. Programınızın tek tek yerine aynı anda daha fazla isteği işleyebilmesi için çatallanırsınız.
cloudhead

fork (), çocukta 0 ve ebeveynde çocuğun pid'ini döndürür. Çocuk daha sonra durumunu yeni bir programla değiştirmek için exec () gibi bir çağrı kullanabilir. Programlar böyle başlatılır.
Todd Gamblin

Süreçler birbirine çok yakındır, ancak pek çok ince fark vardır. Bariz farklılıklar, mevcut PID ve ana PID'dir. Tutulan kilitler ve tutulan semaforlarla ilgili sorunlar var. POSIX için fork () kılavuz sayfası, üst ve alt öğe arasındaki 25 farkı listeler.
Jonathan Leffler

2
@kar: İki işleminiz olduğunda, oradan ayrı olarak devam edebilirler ve biri kendisini (exex ()) tamamen başka bir programla değiştirebilir.
Vatine

4

Uygulama yazıyorsanız, muhtemelen günlük programlamada fork kullanmanıza gerek yoktur.

Programınızın bir görevi yerine getirmek için başka bir programı başlatmasını isteseniz bile, C ve perl'deki "system" gibi arka planda fork kullanan daha basit arayüzler vardır.

Örneğin, uygulamanızın sizin için bir hesaplama yapması için bc gibi başka bir programı başlatmasını istiyorsanız, onu çalıştırmak için 'sistem'i kullanabilirsiniz. Sistem yeni bir süreç yaratmak için bir 'çatal' yapar, sonra bu süreci bc'ye dönüştürmek için bir 'exec' yapar. Bc tamamlandığında, sistem kontrolü programınıza döndürür.

Diğer programları eşzamansız olarak da çalıştırabilirsiniz, ancak nasıl olduğunu hatırlayamıyorum.

Sunucu, kabuk, virüs veya işletim sistemi yazıyorsanız, fork kullanmak isteyebilirsiniz.


İçin teşekkürler system(). Okuyordum fork()çünkü C kodumun bir python betiği çalıştırmasını istiyorum.
Bean Taxi

4

Fork, yeni süreçler yaratır. Çatal olmasaydı, yalnızca init'i çalıştırabilen bir unix sisteminiz olurdu.


4

Sistem çağrısı fork () süreçleri oluşturmak için kullanılır. Hiçbir bağımsız değişken almaz ve bir işlem kimliği döndürür. Fork () işlevinin amacı, arayanın çocuk süreci haline gelen yeni bir süreç yaratmaktır. Yeni bir çocuk süreç oluşturulduktan sonra, her iki süreç fork () sistem çağrısını takip eden sonraki talimatı yürütecektir. Bu nedenle ebeveyni çocuktan ayırmalıyız. Bu, fork () 'un döndürülen değerini test ederek yapılabilir:

Fork () negatif bir değer döndürürse, bir alt sürecin yaratılması başarısız olmuştur. fork (), yeni oluşturulan alt işleme sıfır döndürür. fork (), üst sürecin pozitif bir değeri olan alt sürecin süreç kimliğini döndürür. Döndürülen işlem kimliği, sys / types.h dosyasında tanımlanan pid_t tipindedir. Normalde işlem kimliği bir tamsayıdır. Ayrıca, bir işlem bu işleme atanan işlem kimliğini almak için getpid () işlevini kullanabilir. Bu nedenle, fork () 'a sistem çağrısından sonra, basit bir test hangi sürecin alt öğe olduğunu söyleyebilir. Unix'in ebeveynin adres alanının tam bir kopyasını oluşturup çocuğa vereceğini lütfen unutmayın. Bu nedenle, üst ve alt süreçlerin ayrı adres alanları vardır.

Yukarıdaki noktaları netleştirmek için bir örnekle anlayalım. Bu örnek, ebeveyn ve alt süreçleri ayırt etmez.

Yukarıdaki programın fork () çağrısı noktasına kadar çalıştığını varsayalım.

Fork () çağrısı başarılı bir şekilde yürütülürse, Unix, biri ebeveyn, diğeri alt öğe için olmak üzere iki özdeş adres alanı kopyası oluşturur. Her iki süreç fork () çağrısını izleyen sonraki ifadede yürütülmeye başlayacaktır. Bu durumda, her iki işlem de atamada yürütülmeye başlayacaktır.

Her iki işlem de fork () sistem çağrısından hemen sonra yürütülmeye başlar. Her iki işlem de aynı ancak ayrı adres alanlarına sahip olduğundan, fork () çağrısından önce başlatılan bu değişkenler her iki adres alanında da aynı değerlere sahiptir. Her işlemin kendi adres alanı olduğundan, herhangi bir değişiklik diğerlerinden bağımsız olacaktır. Başka bir deyişle, üst öğe değişkeninin değerini değiştirirse, değişiklik yalnızca üst sürecin adres alanındaki değişkeni etkileyecektir. Fork () çağrıları tarafından oluşturulan diğer adres alanları, aynı değişken adlarına sahip olsalar bile etkilenmeyecektir.

Printf yerine write kullanmanın nedeni nedir? Bunun nedeni, printf () 'nin "arabelleğe alınmış" olmasıdır, yani printf () bir sürecin çıktısını birlikte gruplayacaktır. Üst süreç için çıktıyı arabelleğe alırken, çocuk aynı zamanda arabelleğe alınacak bazı bilgileri yazdırmak için printf kullanabilir. Sonuç olarak çıktı ekrana hemen gönderilmeyeceğinden beklenen sonucun doğru sırasını alamayabilirsiniz. Daha kötüsü, iki işlemin çıktıları tuhaf şekillerde karıştırılabilir. Bu sorunun üstesinden gelmek için, "arabelleğe alınmamış" yazmayı kullanmayı düşünebilirsiniz.

Bu programı çalıştırırsanız, ekranda aşağıdakileri görebilirsiniz:

İşlem Kimliği 3456, ebeveyne veya çocuğa atanan olabilir. Bu süreçlerin eşzamanlı olarak çalıştırılmaları nedeniyle, çıktı hatları oldukça tahmin edilemez bir şekilde birbirine karıştırılmıştır. Ayrıca, bu satırların sırası CPU planlayıcısı tarafından belirlenir. Bu nedenle, bu programı tekrar çalıştırırsanız, tamamen farklı bir sonuç elde edebilirsiniz.


4
Metni kopyalayıp yapıştırmak yerine, bir bağlantıya yorum yazabilirdiniz
chaitanya lakkundi

3

Çoklu işlem, bilgi işlemin merkezidir. Örneğin, IE'niz veya Firefox'unuz siz internette gezinirken sizin için bir dosya indirme işlemi oluşturabilir. Veya, bir kelime işlemcide bir belge yazdırırken, yine de farklı sayfalara bakabilir ve yine de bazı düzenlemeler yapabilirsiniz.


3

Fork (), her vücudun yazdığı gibi yeni süreçler oluşturmak için kullanılır.

İşte ikili ağaç şeklinde süreçler oluşturan kodum ....... İkili ağaçta süreç oluşturmak istediğiniz seviyelerin sayısını taramanızı isteyecek

ÇIKTI


2

İlk önce fork () sistem çağrısının ne olduğunu anlamalı. Açıklamama izin ver

  1. fork () sistem çağrısı, üst işlemin tam olarak kopyasını oluşturur, Üst yığın, yığın, başlatılmış veriler, başlatılmamış verilerin kopyasını yapar ve kodu salt okunur modda üst işlemle paylaşır.

  2. Fork sistem çağrısı, hafızayı yazma üzerine kopyalama esasına göre kopyalar, yani kopyalama gereksinimi olduğunda çocuğun sanal hafıza sayfasında yaptığı anlamına gelir.

Şimdi çatalın Amacı ():

  1. Fork (), bir sunucunun birden fazla istemciyi işlemesi gerektiği gibi iş bölümünün olduğu yerde kullanılabilir, Bu nedenle ebeveyn, bağlantıyı düzenli olarak kabul etmek zorundadır, Bu nedenle, her istemcinin okuma-yazma gerçekleştirmesi için sunucu çatallanır.

1

fork()bir çocuk süreci ortaya çıkarmak için kullanılır. Tipik olarak, iş parçacığı gibi benzer durumlarda kullanılır, ancak farklılıklar vardır. İpliklerden farklı olarak, fork()tamamen ayrı süreçler yaratır, yani çocuk ve ebeveyn fork(), çağrılan noktada birbirlerinin doğrudan kopyaları iken , tamamen ayrıdırlar, hiçbiri diğerinin hafıza alanına erişemez (normal sorunlara gitmeden) başka bir programın belleğine erişmeye gidersiniz).

fork()hala bazı sunucu uygulamaları tarafından, çoğunlukla kullanıcı isteklerini işlemeden önce izinleri bırakan bir * NIX makinesinde root olarak çalışan uygulamalar tarafından kullanılmaktadır. Hala başka kullanım alanları var, ancak çoğu insan şimdi çoklu iş parçacığına geçti.


2
"Çoğu insanın" çok iş parçacıklı çalışmaya geçtiği algısını anlamıyorum. Süreçler ve iş parçacıkları kalıcıdır. İkisinden de kimse "ilerlemedi". Paralel programlamada, en büyük ve en çok eşzamanlı kodlar, dağıtılmış bellekli çoklu işlem programlarıdır (örneğin, MapReduce ve MPI). Yine de, çoğu insan çok çekirdekli bir makine için OpenMP'yi veya bazı paylaşılan bellek paradigmasını tercih ederdi ve GPU'lar bugünlerde iş parçacıkları kullanıyor, ancak bunun ötesinde çok şey var. Yine de bahse girerim, bu sitedeki daha fazla kodlayıcı, çok iş parçacıklı herhangi bir şeyden çok sunucu tarafında işlem paralelliği ile karşılaşıyor.
Todd Gamblin

1

Fork () ile yeni bir işlemi başlatmak için sadece bir exec () işlevine sahip olmanın ardındaki mantık , unix yığın değişimindeki benzer bir soruya yanıt olarak açıklanmaktadır .

Esasen, fork mevcut süreci kopyaladığından, bir süreç için çeşitli olası seçeneklerin tümü varsayılan olarak belirlenir, bu nedenle programcı bunları tedarik edemez.

Windows işletim sisteminde, bunun aksine, programcılar ÇOK daha karmaşık olan ve yeni sürecin parametrelerini tanımlamak için çok çeşitli bir yapı oluşturmayı gerektiren CreateProcess işlevini kullanmak zorundadır.

Yani, özetlemek gerekirse, çatallamanın nedeni (yürütmeye karşı) yeni süreçler yaratmada basitliktir.


0

Fork () sistem çağrısı bir alt süreç oluşturmak için kullanın. Üst sürecin tam bir kopyasıdır. Fork, yığın bölümünü, yığın bölümünü, veri bölümünü, ortam değişkenini, üst öğeden komut satırı argümanlarını kopyalar.

bakın: http://man7.org/linux/man-pages/man2/fork.2.html


0

Çatal () işlev Çağrılış mevcut işlem çoğaltarak yeni bir işlem oluşturmak için kullanılır. Bu işlevin çağrıldığı mevcut süreç ana süreç olur ve yeni oluşturulan süreç alt süreç olur. Daha önce belirtildiği gibi, çocuk ebeveynin kopyasıdır, ancak bunun bazı istisnaları vardır.

  • Çocuğun, işletim sisteminde çalışan diğer tüm işlemler gibi benzersiz bir PID'si vardır.

  • Çocuk, kendisini oluşturan sürecin PID'si ile aynı olan bir üst süreç kimliğine sahiptir
    .

  • Alt süreçte kaynak kullanımı ve CPU zaman sayaçları sıfırlanır.

  • Çocukta bekleyen sinyaller kümesi boş.

  • Çocuk, ebeveyninden herhangi bir zamanlayıcı devralmaz

Misal :

Şimdi, yukarıdaki kod derlendiğinde ve çalıştırıldığında:

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.