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

İş parçacıkları arasında kaynak erişimini eşitlemek, çok iş parçacıklı uygulamalar yazılırken sık karşılaşılan bir sorundur. aynı verilere aynı anda iki veya daha fazla iş parçacığının erişmesi istenmeyen ve öngörülemeyen sonuçlara yol açabilir. Örneğin, bir iş parçacığı bir yapının içeriğini güncelleştirirken, başka bir iş parçacığı aynı yapının içeriğini okuyor olabilir. Okuma iş parçacığının hangi verileri alacağı bilinmiyor: eski veriler, yeni yazılan veriler veya muhtemelen ikisinin bir karışımı. MFC, bu sorunun çözülmesine yardımcı olmak için bir dizi eşitleme ve eşitleme erişim sınıfı sağlar. Bu konu başlığı altında, kullanılabilir sınıflar ve bunların tipik bir çok iş parçacıklı uygulamada iş parçacığı güvenli sınıflar oluşturmak için nasıl kullanılacağı açıklanmaktadır.

Tipik bir çok iş parçacıklı uygulama, iş parçacıkları arasında paylaşılacak bir kaynağı temsil eden bir sınıfa sahiptir. Düzgün tasarlanmış, iş parçacığı açısından güvenli bir sınıf, herhangi bir eşitleme işlevini çağırmanızı gerektirmez. Her şey sınıfın içinde işlenir ve sınıfın nasıl bozulabileceğine değil, en iyi şekilde nasıl kullanılacağına odaklanmanıza olanak sağlar. Tam iş parçacığı güvenli bir sınıf oluşturmak için etkili bir teknik, eşitleme sınıfını kaynak sınıfıyla birleştirmektir. Eşitleme sınıflarını paylaşılan sınıfla birleştirmek basit bir işlemdir.

Örnek olarak, bağlı bir hesap listesi tutan bir uygulama alın. Bu uygulama, ayrı pencerelerde en fazla üç hesabın incelenmesine izin verir, ancak herhangi bir zamanda yalnızca bir hesap 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ü de kullanır. Aynı anda en fazla üç hesabın incelenmesine izin verdiğinden, erişimi üç görünüm nesnesiyle sınırlamak için CSemaphore kullanır. Dördüncü bir hesabı görüntüleme girişimi gerçekleştiğinde, uygulama ilk üç pencereden biri kapanana kadar bekler veya başarısız olur. Bir hesap güncelleştirildiğinde, uygulama aynı anda yalnızca bir hesabın güncelleştirildiğinden emin olmak için CCriticalSection kullanır. Güncelleştirme başarılı olduktan sonra CEvent'e işaret eder ve bu da olayın işaretlenmesi için bekleyen bir iş parçacığı bırakır. Bu iş parçacığı yeni verileri veri arşivine gönderir.

İş Parçacığı Güvenli Sınıf Tasarlama

Sınıfı iş parçacığı açısından tamamen güvenli hale getirmek için, önce paylaşılan sınıflara veri üyesi olarak uygun eşitleme sınıfını ekleyin. Önceki hesap yönetimi örneğinde, görünüm sınıfına bir CSemaphore veri üyesi, bağlı liste sınıfına bir CCriticalSection veri üyesi ve veri depolama sınıfına bir CEvent veri üyesi eklenecekti.

Ardından, sınıftaki verileri değiştiren veya denetlenen bir kaynağa erişen tüm üye işlevlerine eşitleme çağrıları ekleyin. Her işlevde bir CSingleLock veya CMultiLock nesnesi oluşturmanız ve bu nesnenin Lock işlevini çağırmanız gerekir. Kilit nesnesi kapsam dışına çıktığında ve yok edildiğinde, nesnenin yıkıcısı kaynağı serbest bırakarak sizi çağırır Unlock . Elbette, isterseniz doğrudan arayabilirsiniz Unlock .

İş parçacığı güvenli sınıfınızı bu şekilde tasarlamak, çok iş parçacıklı bir uygulamada iş parçacığı güvenli olmayan bir sınıf kadar kolay bir şekilde, ancak daha yüksek güvenlik düzeyiyle kullanılmasını sağlar. Eşitleme nesnesini ve eşitleme erişim nesnesini kaynağın sınıfına kapsüllemek, eşitleme kodunu korumanın dezavantajı olmadan tam iş parçacığı güvenli programlamanın tüm avantajlarını sağlar.

Aşağıdaki kod örneği, m_CritSection paylaşılan kaynak sınıfında ve CSingleLock bir nesnede bildirilen bir veri üyesi (türündeCCriticalSection) kullanarak bu yöntemi gösterir. Paylaşılan kaynağın (türetilen CWinThread) eşitlemesi, nesnenin adresi kullanılarak bir CSingleLock nesne oluşturularak denendi m_CritSection . Kaynağı kilitleme girişiminde bulunuldu ve elde edildiğinde paylaşılan nesne üzerinde çalışma gerçekleştirilir. İş bittiğinde, kaynağın kilidi çağrısıyla Unlockaçı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ış kilit isteği seçeneğine sahip değildir. Bir iş parçacığının serbest hale gelmesi için bekleme süresi sonsuzdur.

Bu yaklaşımın dezavantajları, eşitleme nesneleri eklenmeden sınıfın aynı sınıftan biraz daha yavaş olmasıdır. Ayrıca, nesneyi birden fazla iş parçacığının silmesi olasılığı varsa, birleştirilmiş yaklaşım her zaman çalışmayabilir. Bu durumda, ayrı eşitleme nesnelerini korumak daha iyidir.

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

Ayrıca bkz.

C++ ve MCF ile Çoklu İş Parçacığı Kullanımı