Aracılığıyla paylaş


Çoklu İş Parçacığı Kullanımı: Eşitleme Sınıflarını Kullanma

İzlekler arasındaki kaynak erişimlerinin eşzamanlanması, çok izlekli uygulamalar yazılırken yaygın bir sorundur.İki veya daha fazla iş parçacığının aynı anda, aynı veriye erişimi istenmeyen ve beklenmeyen sonuçlara yol açabilir.Örneğin, bir iş parçacığı yapının içeriklerini güncelleştirirken bir diğer iş parçacığı aynı yapının içeriklerini okuyabilir.Okuma iş parçacığının hangi veriyi alacağı bilinmiyor: eski verileri, yeni yazılmış verileri veya muhtemelen her ikisinin bir karışımını.MFc bu sorunun çözümüne yardımcı olacak birkaç eşitleme ve eşitleme erişim sınıfı sağlar.Bu konu kullanılabilir sınıfları ve tipik bir çok iş parçacıklı uygulamada iş parçacığı içinde korumalı sınıfları oluşturmak için bunların nasıl kullanılabileceğini anlatmaktadır.

Tipik bir çok iş parçacıklı uygulamanın, iş parçacıkları arasında paylaşılacak bir kaynağı gösteren bir sınıfı vardır.Uygun şekilde tasarlanmış ve tamamen iş parçacığı güvenli bir sınıf herhangi bir eşitleme işlevi çağırmanızı gerektirmez.Her şey sınıfa dahili olarak işlenir, bu da sizin sınıfın nasıl bozulabileceğine değil en iyi nasıl kullanılabileceğine yoğunlaşmanıza olanak sağlar.Eşitleme sınıfını kaynak sınıfıyla birleştirme, iş parçacığı açısından tamamen güvenli bir sınıf oluşturmak için etkili bir tekniktir.Eşitleme sınıflarının paylaşılan sınıfta birleştirilmesi sorunsuz bir işlemdir.

Örnek olarak, hesapların bağlanmış bir listesini tutan bir uygulamayı alalım.Bu uygulama üç hesabın ayrı pencerelerde incelenmesine izin verir, ancak yalnızca biri belirli bir zamanda güncelleştirilebilir.Bir hesap güncelleştirildiğinde, güncelleştirilmiş veriler ağ üzerinden bir veri arşivine gönderilir.

Bu örnek uygulama, üç eşitleme sınıfı türünün tümünü kullanır.Bir seferde üçe kadar hesabın incelenmesine izin verdiği için, üç görünüm nesnesine erişimi sınırlamak için CSemaphore öğesini kullanır.Dördüncü bir hesabın görüntülenmesi için bir girişim olduğunda, ya uygulama ilk üç pencereden biri kapanana kadar bekler ya da girişim başarısız olur.Bir hesap güncelleştirildiğinde, her seferinde sadece bir hesabın güncelleştirildiğinden emin olmak için uygulama CCriticalSection öğesini kullanır.Güncelleştirme başarılı olduktan sonra, olayın bildirilmesini bekleyen bir iş parçacığını yayımlayan CEvent'i bildirir.Bu iş parçacığı yeni verileri veri arşivine gönderir.

İş Parçacığı Açısından Güvenli bir Sınıf Tasarlama

Bir sınıfı tam olarak iş parçacığı açısından güvenilir kılmak için öncelikle uygun eşitleme sınıfını paylaşılan sınıflara bir veri üyesi olarak ekleyin.Önceki hesap yönetimi örneğinde bir CSemaphore veri üyesi görünüm sınıfına, CCriticalSection veri üyesi bağlantılı liste sınıfına ve bir CEvent veri üyesi veri depolama sınıfına eklenir.

Daha sonra, sınıftaki verileri değiştiren veya kontrollü bir kaynağa erişen tüm üye işlevlerine eşitleme çağrıları ekleyin.Her işlevde CSingleLock veya CMultiLock nesnesi oluşturup o nesnenin Lock işlevini çağırmanız gerekir.Kilit nesnesi kapsam dışına gider ve yok edilirse, nesnenin yıkıcısı kaynağı serbest bırakarak sizin için Unlock öğesini çağırır.Tabii ki, isterseniz Unlock komutunu doğrudan çağırabilirsiniz.

İş parçacığı açısından güvenli sınıfınızı bu şekilde tasarlanması bunun çoklu iş parçacığı olan uygulamalarda iş parçacığı açısından güvenli olmayan sınıf kadar kolay ancak daha yüksek güvenliğe sahip biçimde kullanılmasına olanak sağlar.Eşitleme nesnesini ve eşitleme erişimi nesnesini kaynağın sınıfına yalıtma eşitleme kodunu sürdürme dezavantajı olmaksızın tamamen iş parçacığı açısından güvenli programlamanın tüm avantajlarını sağlar.

Aşağıdaki kod örneği bu yöntemi paylaşılan kaynak sınıfında ve bir CSingleLock nesnesinde bildirilen bir veri üyesi yani m_CritSection (CCriticalSection türü) kullanarak gösterir.Paylaşılan bir kaynağın eşitlenmesi (CWinThreadöğesinden türetilen) m_CritSection nesnesinin adresini kullanarak bir CSingleLock nesnesi oluşturmayı denemektir.Kaynağı kilitlemek için bir girişimde bulunulur ve bu gerçekleştiğinde paylaşılan nesne üzerinde çalışma yapılır.Çalışma tamamlandığında, kaynak Unlock öğesine bir çağrıyla açılır.

CSingleLock singleLock(&m_CritSection);
singleLock.Lock();
// resource locked
//.usage of shared resource...

singleLock.Unlock();

[!NOT]

CCriticalSection, diğer MFC eşitleme sınıflarından farklı olarak, zamanlanmış kilitleme isteğine dair bir seçeneğe sahip değildir.Bir iş parçacığının serbest hale gelmesine ilişkin bekleme süresi sonsuzdur.

Bu yaklaşımın dezavantajları, sınıfın eşitleme nesneleri eklenmemiş olan sınıftan biraz daha yavaş olacak olmasıdır.Ayrıca, birden çok iş parçacığının nesneyi silme olasılığı varsa, birleştirilmiş bir yaklaşım her zaman işe yaramayabilir.Bu durumda, ayrı eşitleme nesneleri bulundurmak daha iyidir.

Farklı durumlarda hangi eşitleme sınıfının kullanılacağını belirleme konusunda bilgi için bkz. Çoklu İş Parçacığı Kullanımı: Eşitleme Sınıflarını Kullanırken.Eşitleme hakkında daha fazla bilgi için bkz. Windows SDK'de Eşitleme.MFC'de çoklu kullanım desteği hakkında daha fazla bilgi için bkz. C++ ve MFC ile Çoklu Kullanım.

Ayrıca bkz.

Kavramlar

C++ ve mfc çoklu kullanım