İpliklerin ayrı bir yığını var mı?


114

Bildiğim kadarıyla, iş parçacığı işletim sistemi tarafından oluşturulduğunda her iş parçacığı farklı bir yığın alır. Her iş parçacığının kendine özgü bir yığını olup olmadığını merak ediyorum.


evet, windows and linux, c library

3
Güzel. +1 bu temel soruların gelmesini sağlar.

Yanıtlar:


128

Hayır. Tüm iş parçacıkları ortak bir yığını paylaşır.

Her iş parçacığının, öğeleri hızlı bir şekilde ekleyip çıkarabileceği özel bir yığını vardır . Bu, yığın tabanlı belleği hızlandırır, ancak sonsuz özyinelemede olduğu gibi çok fazla yığın belleği kullanırsanız, bir yığın taşması elde edersiniz.

Tüm iş parçacıkları aynı yığını paylaştığından, ayırıcıya / ayırıcıya erişim senkronize edilmelidir. Ayırıcı çekişmesinden kaçınmak için çeşitli yöntemler ve kitaplıklar vardır .

Bazı diller, özel bellek havuzları veya tek bir iş parçacığına atayabileceğiniz ayrı yığınlar oluşturmanıza izin verir.


5
Tipik olarak iş parçacıkları bellek gibi kaynakları paylaşır, bu nedenle herhangi bir braindead olmayan iş parçacığı uygulaması yığını paylaşır.
R. Martinho Fernandes

10
Ana her iş parçacığı kendi bacası mevcuttur sebebi ... iplik aslında (bir işlev çağrısı gibi) şeyler yapabiliriz öyle mi
Edmund

3
Her iş parçacığının ayrı bir yığını vardır, ancak bu mutlaka 'özel' değildir. Diğer konuların erişmesine genellikle izin verilir.
zch

you will get a stack overflow.Stack Overflow'da bir yığın taşması!
John Strood

2
@crisron Her iş parçacığı için ayrı bir yığın oluşturmak mümkündür, ancak bunu varsayılan paylaşılan yığın kullanmak yerine yaparsanız, örneğin A iş parçacığının bir arabellek ayırması, veriyle doldurması, B iş parçacığına iletmesi zorlaşır. ve B iş parçacığının verileri kullanmasını ve ardından arabelleği boşaltmasını sağlayın (çünkü B iş parçacığı A evresine erişemez, B iş parçacığı tamponu serbest bırakamaz; B iş parçacığının yapabileceği en iyi iş parçacığı, tamponu A evresine geri iletmektir. tekrar ve A iş parçacığını serbest bırakın).
Jeremy Friesner

9

Varsayılan olarak, C'de yalnızca tek bir yığın vardır.

Bununla birlikte, iş parçacığı farkında olan bazı ayırıcılar, öbeği böler, böylece her iş parçacığı ayırmak için kendi alanına sahip olur. Buradaki fikir, bunun yığın ölçeğini daha iyi hale getirmesidir.

Böyle bir yığının bir örneği, Hoard'dur .


Varsayılan olarak C ve C ++ birden çok iş parçacığına sahip değildir. 2003 c ++ belirtimi en azından sanal makine tasarımında iş parçacıkları için izin vermez, bu nedenle c ++ 'da iş parçacıkları uygulama tanımlanır.
Chris Becke

Farklı evreler öbek üzerinde tahsis edilecek farklı alanlara sahip olsalar bile, bunlar başka bir evre tarafından ayrılan verileri yine de görebilirler, böylece evreler hala aynı yığını paylaşırlar.
Ken Bloom

1
Güncelleme: C ++ 11'den itibaren iş parçacıkları artık uygulama tanımlı değildir.
Michael Dorst

5

İşletim sistemine bağlıdır. Windows ve unices üzerindeki standart c çalışma zamanı, iş parçacıkları arasında paylaşılan bir yığın kullanır. Bu, her malloc / free'yi kilitlemek anlamına gelir.

Örneğin Symbian'da, her iş parçacığı kendi yığınıyla birlikte gelir, ancak iş parçacıkları herhangi bir yığına ayrılan verilere işaretçileri paylaşabilir. Symbian'ın tasarımı bence daha iyi, çünkü yalnızca ayırma / serbest bırakma sırasında kilitleme ihtiyacını ortadan kaldırmakla kalmıyor, aynı zamanda iş parçacıkları arasında veri sahipliğinin temiz bir şekilde belirtilmesini teşvik ediyor. Ayrıca bu durumda, bir iş parçacığı öldüğünde, kendisiyle birlikte tahsis ettiği tüm nesneleri alır - yani, kısıtlanmış belleğe sahip mobil cihazlarda sahip olması gereken önemli bir özellik olan, tahsis ettiği nesneleri sızdıramaz.

Erlang ayrıca, bir "işlemin" çöp toplama birimi olarak hareket ettiği benzer bir tasarım izler. Referans sayılan ikili bloblar dışında tüm veriler kopyalanarak süreçler arasında iletilir (sanırım).


3

Her iş parçacığının kendi yığını ve çağrı yığını vardır.

Her iş parçacığı aynı yığını paylaşır.


3

"Yığın" derken tam olarak ne demek istediğine bağlı.

Tüm iş parçacıkları adres alanını paylaşır, bu nedenle yığın tahsisli nesnelere tüm evrelerden erişilebilir. Teknik olarak, yığınlar da bu anlamda paylaşılır, yani hiçbir şey diğer iş parçacığının yığınına erişmenizi engellemez (ancak bunu yapmak neredeyse hiçbir zaman mantıklı olmaz).

Öte yandan, bellek ayırmak için kullanılan yığın yapıları vardır . Yığın bellek ayırma için tüm defter tutma işleminin yapıldığı yer burasıdır. Bu yapılar, iş parçacıkları arasındaki çekişmeyi en aza indirmek için sofistike bir şekilde düzenlenmiştir - bu nedenle, bazı iş parçacıkları bir yığın yapısını (bir arena) paylaşabilir ve bazıları farklı alanlar kullanabilir.
Ayrıntıların mükemmel bir açıklaması için aşağıdaki ileti dizisine bakın: malloc çok iş parçacıklı bir ortamda nasıl çalışır?


1

Tipik olarak, iş parçacıkları yığını ve diğer kaynakları paylaşır, ancak paylaşmayan evre benzeri yapılar da vardır. Bu iş parçacığı benzeri yapılar arasında Erlang'ın hafif süreçleri ve UNIX'in tam-açık süreçleri (bir çağrı ile oluşturulmuş fork()) bulunmaktadır. Çok makineli eşzamanlılık üzerinde de çalışıyor olabilirsiniz, bu durumda iş parçacıkları arası iletişim seçenekleriniz önemli ölçüde daha sınırlıdır.


Fork'un daha çok, verileri yeni bir bellek konumuna kopyalayan yeni bir işlem oluşturmaya benzediğini düşündüm.
Jason Tholstrup

2
fork (), iş parçacığının da kullanılabileceği birçok kullanım durumunda hizmet edebilir. Yazma üzerine kopyalama nedeniyle, Unix sistemlerinde önemli bir maliyet farkı yoktur. Tipik kullanım durumu, çalışanın hizmetin geri kalanından özerk olduğu (web sunucusu gibi) durumdur. Diğer bir olasılık, ana iş parçacığı / program ile stdin / out aracılığıyla iletişim kurmaktır. fork () Unix'te güçlüdür, oysa Windows gibi diğer platformlar threading'i tercih eder. Muhtemelen temel neden fork () kullanmanın çok daha basit ve daha güvenli olması ve Unix'in bu basitlik felsefesine sahip olmasıdır. Örneğin iş parçacıklarına yavaş geçişiyle apache web sunucusuna bakın.
ypnos

1

Genel olarak konuşursak, tüm evreler aynı adres alanını kullanır ve bu nedenle genellikle yalnızca bir öbeğe sahiptir.

Ancak biraz daha karmaşık olabilir. İş Parçacığı Yerel Depolaması (TLS) arıyor olabilirsiniz , ancak yalnızca tek değerleri depolar.

Windows'a Özgü: TLS alanı TlsAlloc kullanılarak tahsis edilebilir ve TlsFree kullanılarak serbest bırakılabilir (Genel bakış burada ). Yine, bu bir yığın değil, sadece DWORD'ler.

Garip bir şekilde, Windows işlem başına birden çok Yığını destekler . Yığının tutacağı TLS'de saklanabilir. O zaman "İş Parçacığı Yerel Yığın" gibi bir şeye sahip olursunuz. Ancak, diğer iş parçacıkları yalnızca tanıtıcıyı bilmiyor, yine de aynı adres alanı olduğu için işaretçileri kullanarak belleğine erişebilirler.

DÜZENLEME : Bazı bellek ayırıcılar (özellikle FreeBSD üzerinde jemalloc ) iş parçacıklarına "alan" atamak için TLS kullanır. Bu, senkronizasyon ek yükünü azaltarak birden çok çekirdek için tahsisi optimize etmek için yapılır.


> "Garip bir şekilde, Windows işlem başına birden çok Yığın'ı destekliyor." Hiç de tuhaf değil, farklı tahsis türleri için farklı yığınlar kullanılabilir, sadece daha fazla esneklik ekler. Elbette her zaman VirtualAlloc'a geçebilir ve istediğiniz gibi kendi yığınınızı oluşturabilirsiniz.

1

FreeRTOS İşletim sisteminde görevler (iş parçacıkları) aynı yığını paylaşır, ancak her birinin kendi yığını vardır. Bu, düşük güçlü düşük RAM mimarileriyle uğraşırken çok kullanışlıdır, çünkü aynı bellek havuzuna birkaç iş parçacığı tarafından erişilebilir / paylaşılabilir, ancak bu küçük bir yakalama ile birlikte gelir, geliştiricinin malloc'u senkronize etmek için bir mekanizma olduğunu akılda tutması gerekir. ve ücretsiz gereklidir, bu nedenle yığın üzerinde bellek ayırırken veya serbest bırakırken, örneğin semafor veya muteks gibi bir tür işlem senkronizasyonu / kilidi kullanmak gerekir.

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.