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.
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.
Yanıtlar:
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.
you will get a stack overflow.
Stack Overflow'da bir yığın taşması!
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 .
İş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).
"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?
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.
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.
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.