2010-03-09 17 views
13

Linux'ta okuma/yazma kilitlerini kullanıyorum ve okuma kilitli bir nesneyi bir yazma kilidi kilitlenmesini yükseltmeye çalışıyorum.pthreads: okuyucu/yazıcı kilitleri, okuma kilidini okuma kilidini yükseltme

yani

// acquire the read lock in thread 1. 
pthread_rwlock_rdlock(&lock); 

// make a decision to upgrade the lock in threads 1. 
pthread_rwlock_wrlock(&lock); // this deadlocks as already hold read lock. 

Ben adam sayfasını okudum ve oldukça spesifik var.

çağıran iş parçacığı ise azından okuma-yazma kilidi tutan çağrı yapıldığında zaman kilitlenmeye (ister bir okuma veya yazma kilidi).

ben koruyorum değişkeni bir yarış tanıtmak istemiyorum .. bu koşullarda bir yazma kilidi bir okuma kilidi yükseltmek için en iyi yolu nedir.

Muhtemelen okuma kilidinin bırakılmasını ve yazma kilidinin alınması için başka bir muteks oluşturabilirim ancak okuma/yazma kilitlerinin kullanımını gerçekten göremiyorum. Basit bir normal muteks kullanabilirim.

Thx

+0

Boost.Thread, UpgradeLockable konseptine sahiptir, ancak kodunuz pthreads içinde zaten hip-derinse, bu sizin için çok fazla şüphe duymayacaktır. –

+0

@Steve. Nasıl uygulandığını biliyor musun? Yapmayı düşündüğüm şey olan ayrı bir muteks kullanıyor mu? Sanırım onu ​​indirip kontrol edebilirim: o) – ScaryAardvark

+0

Hayır, Boost'u nasıl bilmiyorum.Onlar bunu yapıyor, üzgünüm. –

cevap

15

Aşağıdaki senaryoda ölü kilit dışında ne istiyorsunuz?

  • iplik 1 acquire iplik 2 acquire 1 Yani ben

yazmak için

  • ipliği 2 yazmak için kilit yükseltme sormak kilidi yükseltmek için sormak
  • iplik kilit okumak
  • kilit okumak d sadece okuma kilidini serbest bırakın, yazma kilidini alın ve güncellemeyi yapıp yapmadığımı kontrol edin.

  • +0

    Diğeri bir okuma kilidi tutuyorsa, iş parçacığı neden yazma kilidini alsın? Ve eğer her ikisi de yazma kilidini alabilirse, ikincisi, korunan kaynak önemli ölçüde değiştirilmiş olabileceğinden, yapılan tüm kontrollerin yeniden yapılmasının gerekeceği problemi olacaktır. Serbest bırakma ve tekrar kazanma aynı davranışı sağlar. – AProgrammer

    +0

    Kilitli olan nesnenin ikinci kontrolünden kaçınmayı umuyordum. IBM'in okuma/yazma kilitleri uygulamasının, bir yazma kilidini tutan tek iş parçacığıysa, bir arama iş parçacığının kilidini yükseltmesine izin verdiğini biliyorum. http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=/apis/users_93.htm – ScaryAardvark

    +0

    @nos. Evet, bu kilitlenme olur. T1, yükseltme istendiğinde T2'nin bir okuma kilidine sahip olması nedeniyle engellenir. T1 daha sonra T1 bir okuma kilidine sahip olduğu için yazma kilidine yükseltme yapılırken bloke olur. – ScaryAardvark

    0

    En kolay ve en güvenli Bunu değiştirmek eminiz yerine andan itibaren sizin verileri değiştirmek istiyor olabilir andan itibaren yazmaya karşı kilidi almak olacaktır. Bunun, verilerinize biraz daha seri hale getirileceğini biliyorum.

    Bu soruyu okurken biraz şaşırdım, çünkü daha önce hiç okuma kilidi almamış ve daha sonra yazma kilidine geçmeyi düşünmedim. Pekala, farklı durum farklı yaklaşımlara ihtiyaç duyabilir.

    +2

    İhtiyaç duyamayacağınız zaman bir yazma kilidi elde etmek için üst kısımda biraz görünüyor. Bu işaret ettiğin gibi serpiştirir. Oysa bir okuma kilidini almamak engellenmez. Bir şeyi değiştirmeniz gerektiğini bildiğiniz noktada, bir yazma kilidine yükseltebilirsiniz. Bunu yapmak için asıl eylem sadece, posix altında, bir utanç olan bir yarış başlatıyor. – ScaryAardvark

    +0

    Bu utanç verici, ama çoğu zaman biliyorum, daha teorik bir fark. – stefaanv

    0

    Pthread okuma/yazma kilidini kullanmak yerine, Posix fcntl() öğesini kullanabilirsiniz. Burada okumadan yazmaya sorunsuzca geçebilirsiniz. B-tree ekleme için kullanıyoruz. Eklemenin gerçekleştiği düğümü tanımaya başladığımızda, kilidi yazmaya yükselteceğiz. Ayrıca, düğümü bölmemiz gerektiğinde, düğümün, ana düğümünün ve çocukların okuduğu yazının kilidini yükselteceğiz. B-ağacı dosya tabanlı bir Veri yapısı olduğundan, dosya bölgesini kilitlemeye yardımcı olur.

    İlgili konular