2013-06-03 16 views
11

Üretici-tüketici modelini kullanarak pthread içeren çok parçalı bir program yazdım.Pthread Mutex: pthread_mutex_unlock() çok fazla zaman harcar

Programımı izlemek için Intel VTune profiler kullanıyorum, üretici ve tüketicinin pthread_mutex_unlock öğesinde çok fazla zaman harcadığını buldum. Bunun neden olduğunu anlamıyorum. Bence iş parçacığı, bir muteks elde edebilmek için uzun bir süre bekleyebilir, ama bir muteks salmak hızlı olmalı, değil mi?

Aşağıdaki anlık görüntü Intel VTune'den alınmıştır. Tüketicinin bir öğeyi arabellekten almaya çalıştığı kodları ve her kod satırı tarafından tüketilen zamanı gösterir.

Soruma göre pthread_mutex_unlock neden bu ek yüke sahip? Sorun pthread muteks'in kendisi mi yoksa onu kullanma şeklim mi? enter image description here

+0

Bir muteks kilidini açmak, bu mutekste çok fazla çekişme varsa yavaş olabilir, çünkü kilidin açılması işinin bir kısmı mutekste bekleyen tüm konuları uyandırıyor. – caf

+6

"pthread_mutex_unlock()" çağrısını "pthread_cond_signal()" seçeneğinin üzerine getirdiğinizde sonuçları görmek ilginç olur. Koşul değişkenini işaret ederken muteks tutmaya gerek yok (sadece beklerken) ve sinyalin mutekste çekişmeye yol açtığından şüpheleniyorum çünkü serbest bırakılan iplik derhal muteks elde etmeye çalışır. Sinyal dişi hala duruyor. –

+2

@MichaelBurr İyi nokta! Önerilerinizi test ediyorum ve program şu an yaklaşık% 40 daha hızlı. –

cevap

2

pthread_mutex_unlock() işlevi muteks tarafından başvurulan mutex nesnesini serbest bırakmalıdır. Ancak, bir muteksin serbest bırakılma biçimi muteksin tip özniteliğine bağlıdır. Eğer pthread_mutex_unlock() çağrıldığında muteks tarafından başvurulan muteks nesnesinde engellenen iş parçacıkları varsa, muteks elde edilebilir duruma gelir, zamanlama ilkesi hangi iş parçacığının mutex'i edineceğini belirler.

Eğer muteks tipi PTHREAD_MUTEX_NORMAL ise, kilitlenme tespiti sağlanamaz. Muteks yeniden kilitlemeye çalışırken kilitlenme neden olur. Bir iş parçacığı kilitlenmemiş bir muteksin kilidini açmaya çalışırsa veya kilitlenmemiş bir muteksle tanımlanırsa, tanımlanmamış davranış sonuçları olur.

Eğer muteks tipi PTHREAD_MUTEX_ERRORCHECK ise, hata kontrolü sağlanacaktır. Eğer bir iplik zaten kilitlenmiş bir muteksin yeniden başlatılmasını denerse, bir hata iade edilir. Eğer bir iplik kilitlenmemiş bir muteksin kilidini açmaya çalışırsa veya kilidi açılmış bir muteksse, bir hata iade edilir.

Eğer muteks tipi PTHREAD_MUTEX_RECURSIVE ise, muteks bir kilit sayısı kavramını sürdürmelidir. Bir iş parçacığı ilk kez bir muteks elde ettiğinde, kilit sayısı bire ayarlanır. Bir iş parçacığı her zaman bu muteksin yerini alır, kilit sayısı bir artırılır. İplik muteks kilidini her açışında, kilit sayısı bir azaltılır. Kilit sayısı sıfıra ulaştığında, muteks elde edilecek diğer dişler için kullanılabilir hale gelecektir. Eğer bir iplik kilitlenmemiş bir muteksin kilidini açmaya çalışırsa veya kilidi açılmış bir muteksse, bir hata iade edilir.

Eğer muteks tipi PTHREAD_MUTEX_DEFAULT ise, mutex'i yinelemeli olarak kilitlemeye çalışmak tanımsız bir davranışla sonuçlanır. Çağırma iş parçacığı tarafından kilitlenmemişse muteks kilidini açma girişimi, tanımlanmamış bir davranışla sonuçlanır. Kilitlenmemişse muteks kilidini açmaya çalışmak, tanımlanmamış bir davranışla sonuçlanır.

Genellikle PTHREAD_MUTEX_RECURSIVE mutekslerini kullanmayı tercih ediyorum, çünkü bu durumda, muteks, sayım sıfıra ulaştığında ve çağıran iş parçacığı artık bu mutekste kilitlenmediğinde kullanılabilir hale gelecektir.

İlgili konular