İplik çekişmesi nedir?


121

Can someone please explain simply what thread contention is?

I have googled it, but cannot seem to find a simple explanation.


10
So write out what your vague thought is on it, so we can see where you may be off, or your understanding may be correct.
James Black

Yanıtlar:


88

Essentially thread contention is a condition where one thread is waiting for a lock/object that is currently being held by another thread. Therefore, this waiting thread cannot use that object until the other thread has unlocked that particular object.


53
This answer is incomplete (as are most of the others). While a lock is one type of thing that there can be contention over, it is far from the only such thing. There can be contention for lockless resources as well. (For example, if two threads keep atomically incrementing the same integer, they may experience contention due to cache ping-ponging. No locks are involved.)
David Schwartz

In the case of a Global Interpreter Lock (GIL) such as in CPython, where a thread must always acquire the GIL, multiple threads running in the same process are therefore in contention by default.
Acumenus

Bunu Deadlock açısından açıklamış olduğunuzu düşünüyorum ama Deadlock'tan çok farklı.
Harshit Gupta 04

185

Several answers seem to focus on lock contention, but locks are not the only resources on which contention can be experienced. Contention is simply when two threads try to access either the same resource or related resources in such a way that at least one of the contending threads runs more slowly than it would if the other thread(s) were not running.

The most obvious example of contention is on a lock. If thread A has a lock and thread B wants to acquire that same lock, thread B will have to wait until thread A releases the lock.

Şimdi, bu platforma özeldir, ancak diğer iş parçacığının kilidi açmasını beklemek zorunda kalmasa bile iş parçacığı yavaşlamalar yaşayabilir! Bunun nedeni, bir kilidin bir tür veriyi korumasıdır ve verilerin kendisi de çoğu zaman kontrol edilecektir.

Örneğin, bir kilit alan, bir nesneyi değiştiren, ardından kilidi serbest bırakan ve başka şeyler yapan bir iş parçacığı düşünün. İki iş parçacığı bunu yapıyorsa, kilit için asla savaşmasalar bile, iş parçacığı yalnızca bir iş parçacığı çalışıyorsa olduğundan çok daha yavaş çalışabilir.

Neden? Her iş parçacığının modern bir x86 CPU'da kendi çekirdeğinde çalıştığını ve çekirdeklerin bir L2 önbelleğini paylaşmadığını varsayalım. Tek bir iş parçacığı ile nesne çoğu zaman L2 önbelleğinde kalabilir. Her iki evre çalışırken, bir evre nesneyi her değiştirdiğinde, diğer iş parçacığı verinin L2 önbelleğinde olmadığını bulacaktır çünkü diğer CPU önbellek satırını geçersiz kılmıştır. Örneğin bir Pentium D'de bu, kodun L2 önbellek hızından çok daha düşük olan FSB hızında çalışmasına neden olur.

Kilit kendi başına uğraşmasa bile çekişme olabileceğinden, kilit olmadığında da çekişme meydana gelebilir. Örneğin, CPU'nuzun 32 bitlik bir değişkenin atomik artışını desteklediğini varsayalım. Bir iş parçacığı bir değişkeni artırmaya ve azaltmaya devam ederse, değişken önbellekte çoğu zaman sıcak olacaktır. Eğer iki iş parçacığı bunu yaparsa, önbellekleri bu değişkeni tutan belleğin sahipliği için mücadele edecek ve önbellek tutarlılık protokolü, önbellek hattının her bir çekirdek sahipliğini güvence altına almak için çalıştığı için birçok erişim daha yavaş olacaktır.

İronik olarak, kilitler tipik olarak çekişmeyi azaltır . Neden? Çünkü bir kilit olmadan, iki iş parçacığı aynı nesne veya koleksiyon üzerinde çalışabilir ve çok fazla çekişmeye neden olabilir (örneğin, kilitsiz kuyruklar vardır). Kilitler, rekabet eden iş parçacıklarının zamanlamasını kaldırma eğiliminde olacak ve bunun yerine çekişmeyen iş parçacıklarının çalıştırılmasına izin verecektir. İplik A bir kilit tutuyorsa ve iplik B aynı kilidi istiyorsa, uygulama onun yerine C ipliğini çalıştırabilir. C dişlisi bu kilide ihtiyaç duymuyorsa, A ve B evreleri arasında gelecekteki çekişmeler bir süreliğine önlenebilir. (Elbette, bu, çalışabilecek başka iş parçacığı olduğunu varsayar. Sistemin bir bütün olarak yararlı ilerleme kaydetmesinin tek yolu, yarışan iş parçacıkları çalıştırmaksa yardımcı olmaz.)


4
+1 Ayrıca, bunu açıkça belirtmek için, iki çekirdeğin üzerinde mücadele ettiği iki değişkenin, çekişmeye neden olmak için aynı değişken olması gerekmez, yalnızca aynı önbellek satırında bellekte depolanmaları gerekir. Yapıları doldurmak ve / veya yapıları belleğe hizalamak, bu tür bir çekişmeden kaçınmaya yardımcı olabilir.
Rob_before_edits

1
@David, lütfen cevabınızın son paragrafını daha ayrıntılı olarak anlamanıza yardımcı olun
Öğrenci

4
@Naroji Bununla ilgili bir soru sorun.
David Schwartz

@DavidSchwartz, C programcısı mısınız?
Pacerier

@Pacerier C ++ çoğunlukla.
David Schwartz

19

Gönderen burada :

Bir iş parçacığı, hazır olmayan bir kaynağı beklediğinde bir çekişme meydana gelir; kodunuzun yürütülmesini yavaşlatır, ancak zamanla düzelebilir.

Bir iş parçacığı, ikinci bir iş parçacığının kilitlediği bir kaynağı beklediğinde ve ikinci iş parçacığı, birinci iş parçacığının kilitlediği bir kaynağı beklediğinde bir kilitlenme oluşur. Bir kilitlenmeye ikiden fazla iş parçacığı dahil olabilir. Bir kilitlenme asla kendi kendine çözülmez. Genellikle tüm uygulamanın veya kilitlenme yaşayan parçanın durmasına neden olur.


Bu aynı zamanda İş Parçacığı Çatışması ile Kilitlenme arasındaki farkı da açıklıyor
Sankalp

3

Sorunun arka planında OP'den bazı açıklamalar olması gerektiğini düşünüyorum - 2 cevap düşünebilirim (yine de bu listeye eklemeler olduğundan eminim):

  1. İplik çekişmesinin genel "kavramından" ve kendisini bir uygulamada nasıl sunabileceğinden bahsediyorsanız, @ DavidSchwartz'ın yukarıdaki ayrıntılı cevabına başvuruyorum.

  2. Ayrıca '.NET CLR Kilitleri ve İş Parçacığı: Toplam Çekişme Sayısı' Performans Sayacı da vardır. Bu sayaç için PerfMon açıklamasından alındığı gibi, şu şekilde tanımlanır:

    Bu sayaç, CLR'deki iş parçacıklarının başarısız bir şekilde yönetilen bir kilidi elde etmeye çalıştığı toplam sayısını gösterir. Yönetilen kilitler birçok şekilde edinilebilir; C # 'daki "kilit" ifadesiyle veya System.Monitor.Enter çağırarak veya MethodImplOptions.Synchronized özel özniteliğini kullanarak.

... ve eminim diğer işletim sistemleri ve uygulama çerçeveleri için diğerleri.


2

2 ileti diziniz var. İplik A ve İplik B, ayrıca C nesnesine sahipsiniz.

A şu anda C nesnesine erişiyor ve bu nesneye bir kilit yerleştirdi. B'nin C nesnesine erişmesi gerekir, ancak A nesnesi C üzerindeki kilidi serbest bırakana kadar bunu yapamaz.


1

Başka bir kelime eşzamanlılık olabilir. Basitçe, aynı kaynağı kullanmaya çalışan iki veya daha fazla iş parçacığı fikridir.


1

Benim için çekişme, paylaşılan bir kaynak üzerinden 2 veya daha fazla konu arasındaki bir rekabettir. Kaynak bir kilit, sayaç vb. Olabilir. Rekabet "ilk kim alır" anlamına gelir. Ne kadar çok iş parçacığı olursa o kadar çok çekişme olur. Bir kaynağa daha sık erişim, daha fazla çekişme demektir.


1

Aşağıdaki senaryoyu hayal edin. Yarınki final sınavına hazırlanıyorsunuz ve biraz aç hissediyorsunuz. Yani, küçük kardeşine on dolar veriyorsun ve ondan sana pizza almasını istiyorsun. Bu durumda, ana konu sizsiniz ve erkek kardeşiniz bir çocuk ipliği. Siparişiniz verildikten sonra, hem siz hem de erkek kardeşiniz aynı anda işlerini yapıyorsunuz (yani, ders çalışıyor ve pizza alıyor). Şimdi, dikkate almamız gereken iki durum var. Birincisi, erkek kardeşiniz pizzanızı geri getiriyor ve siz ders çalışırken bitiriyor. Bu durumda, çalışmayı bırakıp pizzanın tadını çıkarabilirsiniz. İkinci olarak, çalışmanızı erken bitirirsiniz ve pizza hazır olmadan önce uyursunuz (yani, bugün için atanan işiniz - yarınki final sınavı için çalışılır). Tabii ki uyuyamazsınız; aksi takdirde pizzayı yeme şansınız olmaz.

Örnekte olduğu gibi, iki durum rekabet anlamına gelir.


0

İş parçacığı çekişmesi de G / Ç işlemlerinden etkilenir. Dosyanın okunmasını bekleyen bir Konu, bir çekişme olarak değerlendirilebilir. Çözüm olarak G / Ç tamamlama bağlantı noktalarını kullanın.


0

Kilit çekişmesi, bir evre başka bir evre * tarafından zaten elde edilmiş olan bir nesneye kilidi almaya çalıştığında gerçekleşir. Nesne serbest bırakılıncaya kadar, iş parçacığı bloke edilir (diğer bir deyişle Bekleme durumundadır). Bazı durumlarda, bu, uygulamayı olumsuz yönde etkileyen sözde seri yürütmeye yol açabilir.

dan dotTrace belgelerinde

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.