Konular vs (Çatallı) İşlemler


9

Linux uygulamaları genellikle exec (execve () ile), ancak Java uygulamaları ve bazı Apache MPM'leri iş parçacığı kullanır. Çatallanıyorsa, bir işlem oluşturmak için fork + exec kullanırsa, diş çekme için üst düzey sürüm nedir? JVM veya Çalışan MPM konuları nasıl doğurur?


2
Stackoverflow'u kontrol edin. Bunun bir kısmını açıklayan birkaç soru cevap var.
Henk Langeveld

Yanıtlar:


13

İş parçacıklarının ve işlemlerin arkasındaki fikir hemen hemen aynıdır: Yürütme yolunu kesersiniz. Aksi takdirde, iş parçacıkları ve işlemler bellek gibi şeylerde farklılık gösterir. Yani süreçler farklı VM alanına sahipken, iş parçacıkları bölünmeden önce var olanı paylaşıyor.

Clone () çağrısını (man 2 clone) kullanarak hem diş çekme hem de çatallama işinin altında yatan:

Çataldan (2) farklı olarak, clone (), alt işlemin yürütme bağlamının bir bölümünü bellek alanı, dosya tanımlayıcıları tablosu ve sinyal işleyicileri tablosu gibi çağıran işlemle paylaşmasına izin verir. (Bu manuel sayfada "arama işlemi" normal olarak "ana işlem" e karşılık gelir. Ancak aşağıdaki CLONE_PARENT açıklamasına bakın.)

Clone () yönteminin ana kullanımı, paylaşılan bellek alanında eşzamanlı olarak çalışan bir programda iş parçacıkları uygulamaktır: birden çok denetim iş parçacığı.

Farklılıklar klon () 'a geçirilen bayraklardan gelir. Man sayfasında görebileceğiniz gibi, çatal ve diş çekme, klon () için önceden tanımlanmış parametrelerden sadece birkaçıdır. Bununla birlikte, onunla özel şeyler de yapılabilir.


1
Uhm? Ne? Lütfen konuyla ilgili hemen hemen her kitabı tekrar okuyun, çünkü işlemler için ayrı bellek alanı oldukça önemli. Ayrıca, çöken kodun "yakalanmasına" yardımcı olurken, çekirdek basitçe tek bir iş parçacığının haywire / trespasses yaptığı bir işlemi öldürür.
0xC0000022L

3
@ 0xC0000022L argümanınız bana göründüğü gibi cevapla çelişmiyor.
Ruslan

1
@Ruslan: Farklı olmaya yalvarıyorum: "Fikir [...] hemen hemen aynı." İş parçacıklarının ardındaki fikir gerçekten eşzamanlılıktır, ancak süreçler için bu tamamen farklı bir hikaye.
0xC0000022L

4
@ 0xC0000022L V13'ün cevabının önemli bölümünü kaçırdınız: "Yürütme yolunu
çatallıyorsunuz

@Izkata: hiç de değil. Sadece bunun doğru bir iddia olmadığını düşünüyorum.
0xC0000022L

8

Çoğu Unix olmayan çok işlemli işletim sistemi (OS), bir "spawn ()" çağrısı veya yeni bir OS işlemi veya kontrol akışı oluşturmak için benzer bir şey kullanır. Spawn (), birçok seçenek ve ek yük ile çok karmaşık bir çağrı olma eğilimindedir. Unix'in yeniliklerinden biri, süreçler oluşturmak için çok daha düşük bir havai yol sağlamaktı - fork (). Unix, execwn () ile spawn () 'ın diğer yarısından önce rasgele miktarlarda işleme izin vererek spawn () için birçok gerekli seçeneğe dikkat etti.

Unix ve bunların varyantları gittikçe daha fazla kullanıldığından, düşük genel gider işleminin yaratılmasının faydalı olduğu bulundu ve kullanıldı. Aslında, o kadar çok kullanıldı ki, insanlar süreçler oluşturmak için daha düşük havai yollar bile istediler ve böylece "iş parçacıkları" fikri doğdu. Başlangıçta, iş parçacıkları tamamen kaynak işlemiyle işlendi (ve JVM gibi programlar bunu "yeşil iş parçacıklarıyla" yapabilir); ancak çok iş parçacıklı zamanlamayı kullanmak zor ve sık sık yanlış yapılıyordu. Bu nedenle, işletim sisteminin zamanlamayı işlediği ancak iş parçacıkları arasındaki adres alanını (tipik olarak) paylaşarak iş yükünü azaltmanın daha kolay ve orta bir yolu vardır.

Sorunuzun cevaplanması zordur, çünkü hepsi "iş parçacığı" olan birkaç farklı ancak ilgili kavram vardır ve ayrıntı için hangisine başvurduğunuzu açıklamak için bir sıfıra ihtiyacınız vardır. Diğer yandan, farklılıkları anlamak muhtemelen sizi istediğiniz cevaba götürecektir. Daha fazla bilgi için "hafif işlemler", "kullanıcı konuları" ve "rfork ()" gibi şeylere bakın.


1
"çok iş parçacıklı zamanlamayı işlemek zor ve sık sık yanlış yapıldı" alıntı gerekli. Kullanıcı alanı iş parçacıklarını uygulamak sorun değil. Kullanıcı alanı iş parçacığı ile ilgili sorun, bir iş parçacığı engelleme sistem çağrısı yaparsa tüm iş parçacıkları engellenir olmasıdır. Bundan kaçınmanın tek yolu sistem düzeyinde iş parçacıkları kullanmaktır.
Bakuriu

1
İlginçtir, Windows bu Unix yeniliğini içermiyordu: Buna CreateProcess()benzer bir şey yok fork().
Ruslan

2
@Bakuriu - çok işlemli programlayıcılar oluşturma, adaleti koruma, açlıktan kaçınma, öncelikleri kullanma, vb. İle ilgili birçok makaleden herhangi birine bakın. Önemsiz örnekleri planlamak zordur.
mpez0

@Ruslan: Windows'da çatallanabilir, sadece Win32 API'nin bir parçası değildir. Nebbett'in "Windows NT / 2000 Yerel API" nı okuyun. Taklit eden bir uygulaması var fork().
0xC0000022L

3

Dişler ve çatallar aslında her ikisi de Unix / Linux sistemlerinde bulunan (ve her ikisi de C / C ++ 'da kullanılabilen) iki farklı kavramdır.

Bir fork () fikri, (temelde) üst işlemle aynı yürütme koduna sahip olan ve çatal çizgisinde yürütmeye başlayan ayrı bir işlemin oluşturulmasıdır. Exec işlevli çatalları kullanmanın amacı, exec işlevlerinin sona erdiğinde çağrılan işlemi kapatmasıdır. Bu nedenle, genellikle çatallanır, her işlemin PID'sini alırsınız (çocuğun her zaman 0'dır) ve ebeveyn, çocuk exec işlevini yürütmeyi bitirene kadar bekletir.

İplikler paralellik için kullanılır (ebeveynin çocuğu genellikle çatallı bir programda beklediğini hatırlayın). C / C ++ 'da pthread (bir Google araması yapın) gibi bir iş parçacığı, ana sürece paralel olarak çalışır ve global değişkenleri ve global işlevleri orijinal programla paylaşabilir. Java iş parçacıkları benzer şekilde davrandığından, bir çatal işleminden çok bu iş parçacıkları gibi hareket ettiklerini düşünürdüm.

Temel olarak, çatallama ve diş çekme arasında bir fark vardır. (Farklı görünseler de) belirgin şekilde farklı şeyler yaparlar. Bu kavramları anlamak zor olabilir, ancak bunları anlamak için dürüst bir arzunuz varsa (kapsamlı) araştırma yoluyla öğrenebilirsiniz.

DÜZENLEME # 1

Lütfen çatalların ve dişlerin nasıl çağrılabileceği ve kullanılabileceğine ilişkin bu örneklere bakın. Lütfen exec işlevlerinin davranışını ve bunların ana program üzerindeki etkilerini not edin.

http://www.jdembrun.com:4352/computerScience/forkVSthread.zip


2
Çatal (exec ile veya exec olmadan) paralellik için de kullanılabilir. "Exec fonksiyonları sona erdiğinde onlara çağrılan işlemi kapat" derken ne demek emin değilim, exec uzun zaman bittiğinde işlem bitmiş bitmiş. Ayrıca pthreadbir iş parçacığı uygulaması değil, bir API.
Mat

Çatalla ilgili olarak, OS öğretmenimi aktarıyorum. Bize söylediklerine göre, evet, çatallama paralel koşmak için kullanılabilir, ancak bir exec işlevi kullansaydı, sonuncusu olurdu. İkinci aşamaya gelince, bu bir örnekti.
jaredad7

Exec, çatallı sürecin son talimatı değil, arayanın kodundaki son çağrı olacaktır. Çatallı işlem, yürütülen kodu çalıştırırken yaşayacaktır.
Mat

Yorumlarınız bu şeyleri test etmemi istedi. Ben çatal işlevler vs iş parçacığı kullanıldığında exec işlevlerinin davranışlarını ve programları üzerindeki etkileri göstermek bazı c ++ programları yazdım. Lütfen yukarıdaki düzenlemeye bakın.
jaredad7

Korkarım çoğu insan bunu indirmek için uğraşmaz. Ayrıca örnekleriniz , çoğunlukla adres alanının paylaşılması (veya olmaması) ile ilgili modeller arasındaki ilginç farklılıkları göstermemektedir .
Mat

1

Hem JVM hem de Apache MPM, yerel iş parçacıkları için çekirdeğe güvenir. Yani, onları programlamak için işletim sistemini kullanırlar. Tabii ki, her ikisini de takip etmek için kendi API'sine ihtiyaç duyar.

Stackoverflow'un bununla ilgili birkaç sorusu var:

  1. JVM yerel dizileri , daha fazla ayrıntı için bu cevaba göz atın.

  2. Apache'nin iki tür MPM'si vardır: İş parçacığı başına bir işlem içeren Prefork ve birden çok iş parçacığını işleyen Worker: Apache MPM'ler . Referansını inceleyincodebucket


1

Çatallanıyorsa, bir işlem oluşturmak için fork + exec kullanırsa, diş çekme için üst düzey sürüm nedir? JVM veya Çalışan MPM konuları nasıl doğurur?

Bu platforma özgüdür, ancak linux ve diğer birçok POSIX uyumlu sistemi , bir kullanıcı alanı iş parçacığı API'sı olan pthreads'nin yerel uygulamasını kullandıklarını varsayarım . Örneğin:

#include <pthread.h>

pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);

somefuncİlk yürütme noktası olarak yeni bir iş parçacığı çağrısı başlatır .

Ayrıca iş parçacıkları da oluşturabilirsiniz - çatallardan farklı olarak , üst işlemin aynı global yığın bellek alanını paylaşmaları, yinelenen bir kopyasını almak yerine (ancak her birinin kendi bağımsız bir yığın belleği ile yürütüldüğünü unutmayın ) - ile clone()pthreads üzerine inşa budur sistem çağrısı.

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.