Semafor - İlk sayımın kullanımı nedir?


91

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

Bir semafor oluşturmak için, bir ilk sayım ve maksimum sayım sağlamam gerekiyor. MSDN, ilk sayımın -

Eşzamanlı olarak verilebilen semafor için ilk istek sayısı.

Maksimum sayının olduğunu belirtirken

Semafor için aynı anda verilebilecek maksimum istek sayısı.

Maksimum sayının bir kaynağa aynı anda erişebilen maksimum iş parçacığı sayısı olduğunu anlayabiliyorum. Ancak, ilk saymanın faydası nedir?

İlk sayısı 0 ve maksimum sayısı 2 olan bir semafor oluşturursam, iş parçacığı iş parçacıklarının hiçbiri kaynağa erişemez. İlk sayımı 1 ve maksimum sayımı 2 olarak ayarlarsam, yalnızca iş parçacığı havuzu iş parçacığı kaynağa erişebilir. Sadece hem ilk sayımı hem de maksimum sayımı 2 olarak ayarladığımda, 2 iş parçacığı kaynağa aynı anda erişebilir. Yani, ilk sayımın önemi konusunda gerçekten kafam karıştı mı?

SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently

7
SVGreg'in cevabını neden hiç kabul etmedin?
John

Yanıtlar:


79

Evet, ilk sayı 0 olarak ayarlandığında - "CurrentCount" özelliğini artırırken tüm iş parçacıkları bekliyor olacak. Release () veya Release (Int32) ile yapabilirsiniz.

Bırak (...) - semafor sayacını artırır

Bekleyin (...) - azaltacak

Sayacı ("CurrentCount" özelliği), başlatma sırasında belirlediğiniz maksimum sayıdan daha fazla arttıramazsınız.

Örneğin:

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()

1
Kodunuz bir yorumdan ziyade yanıtta daha iyi sunulacaktır.
ChrisF

14
LOL, bu aynı cevaba ulaşmam muhtemelen 5. seferdir çünkü kurucunun dokümantasyonu her zaman beni hangi değerlerin ayarlanacağı konusunda karıştırır. Şerefe
BlueStrat

71

Yani, ilk sayımın önemi konusunda gerçekten kafam karıştı mı?

Burada yardımcı olabilecek önemli bir nokta Wait, semafor sayısını azaltması ve artırmasıdır Release.

initialCounthemen izin verilecek kaynak erişimlerinin sayısıdır. Ya da başka bir deyişle, Waitsemaforun somutlaştırılmasından hemen sonra bloklama yapılmadan çağrılabilecek sayıdır .

maximumCountsemaforun elde edebileceği en yüksek sayıdır. Sayımın sıfır olduğu Releasevarsayılarak bir istisna atılmadan çağrılabilecek sayıdır initialCount. Eğer semafor oluşturulduktan hemen sonra çağırmakla initialCountaynı değere ayarlanırsa, bir istisna atılır.maximumCountRelease


20
Bu çok yardımcı oluyor! Başlangıçtaki ENGELLENEN kaynakların sayısı olduğu için Semaforları geriye doğru düşünüyordum, hemen kullanılabilir olan kaynakların sayısı değil. Teşekkür ederim.
Philip Tenn

5
@PhilipTenn, kabul ediyorum - bu konuda belgeler net değil
BlueStrat

Kabul ettim, bu değişkenin adını değiştirmeleri veya belgeleri güncellemeleri gerekiyor
IronHide

@Sandbox, initialCountparametrenin anlamını gerçekten açıkladığı için bu yanıtı IMO'yu kabul etmelisiniz .
Michal Turczyn

8

Kaynağa aynı anda erişebilmek için kaç iş parçacığı istiyorsun? İlk sayınızı bu sayıya ayarlayın. Bu sayı programın ömrü boyunca asla artmayacaksa, maksimum sayınızı da bu sayıya ayarlayın. Bu şekilde, kaynağı nasıl serbest bırakacağınızla ilgili bir programlama hatanız varsa, programınız çökecek ve size haber verecektir.

(İki kurucu vardır: biri yalnızca bir başlangıç ​​değeri alan ve diğeri ek olarak maksimum sayıyı alan. Uygun olanı kullanın.)


1

Bu şekilde, mevcut iş parçacığı semaforu oluşturduğunda, başlangıçtan itibaren bazı kaynakları talep edebilir.


Yani, iki çalışan iş parçacığının kaynağa erişmesini istediğimde ilk sayımı değiştirmem gerektiğini mi söylüyorsun?
Sandbox

Hayır. Bir sayım talep eden mevcut iş parçacığıdır. Geçerli iş parçacığının herhangi bir erişim geçişini talep etmesini veya aşırı yüklemeyi bir parametre ile kullanmasını istemiyorsanız.
Erno

1

Herhangi bir iş parçacığının kaynağınıza bir süre erişmemesini istiyorsanız, ilk sayımı 0 olarak geçirirsiniz ve semaforu oluşturduktan hemen sonra hepsine erişim izni vermek istediğinizde, başlangıç ​​sayısının değerini maksimum sayıya eşit olarak iletirsiniz. . Örneğin:

hSemaphore = CreateSemaphoreA(NULL, 0, MAX_COUNT, NULL) ;

//Do something here
//No threads can access your resource

ReleaseSemaphore(hSemaphore, MAX_COUNT, 0) ;

//All threads can access the resource now

MSDN Dokümantasyonunda belirtildiği gibi - "ReleaseSemaphore'un başka bir kullanımı, bir uygulamanın başlatılması sırasındadır. Uygulama, başlangıç ​​sayımı sıfır olan bir semafor oluşturabilir. Bu, semaforun durumunu sinyalsiz olarak ayarlar ve tüm iş parçacıklarının korumalı kaynağa erişmesini engeller. başlatmayı bitirdiğinde, korumalı kaynağa normal erişime izin vermek için sayımı maksimum değerine çıkarmak için ReleaseSemaphore kullanır. "


Üzgünüm, size C ++ örneğini verdim ama şüpheyi ortadan kaldırabilir.
Abhineet

0

Semaforlar, bir kaynak havuzunu korumak için kullanılabilir . Veritabanı bağlantıları gibi oluşturulması pahalı olan şeyleri yeniden kullanmak için kaynak havuzlarını kullanırız .

Bu nedenle ilk sayım, bir işlemin başlangıcında havuzda bulunan mevcut kaynakların sayısını ifade eder. initialCountKodu okuduğunuzda, bu kaynak havuzunu oluşturmak için ne kadar ön çaba harcadığınızı düşünmelisiniz.

İlk sayımın önemi konusunda gerçekten kafam mı karıştı?

Initial count = Upfront cost

Bu nedenle, uygulamanızın kullanım profiline bağlı olarak bu değer, uygulamanızın performansı üzerinde önemli bir etkiye sahip olabilir. Bu sadece rastgele bir sayı değil.

Ne yarattığınızı, yaratmanın ne kadar pahalı olduğunu ve hemen kaç tanesine ihtiyacınız olduğunu dikkatlice düşünmelisiniz. Kelimenin tam anlamıyla bu parametre için en uygun değeri grafiklendirebilmelisiniz ve yapılandırılabilir hale getirmeyi düşünmelisiniz, böylece işlemin performansını yürütüldüğü zamana uyarlayabilirsiniz.


-1

As MSDN Açıklamalar bölümünün altına açıklıyor:

İnitialCount, maximumCount değerinden küçükse, etki, geçerli iş parçacığının WaitOne (maximumCount eksi initialCount) zamanlarını çağırması ile aynıdır. Semaforu oluşturan iş parçacığı için herhangi bir girdi ayırmak istemiyorsanız, maximumCount ve initialCount için aynı sayıyı kullanın.

Bu nedenle, ilk sayı 0 ve maksimum 2 ise, WaitOne ana iş parçacığı tarafından iki kez çağrılmış gibidir, böylece kapasiteye ulaştık (semafor sayısı şimdi 0'dır) ve hiçbir iş parçacığı Semafora giremez. Benzer şekilde İlk sayı 1 ve maksimum 2 ise WaitOnce bir kez çağrılır ve kapasiteye tekrar ulaşmadan önce yalnızca bir iş parçacığı girebilir ve bu böyle devam eder.

İlk sayım için 0 kullanılırsa, kaynak elde etmek için maksimum iş parçacığı sayısına izin vermek için semafor sayısını maksimuma çıkarmak için her zaman Release (2) 'yi çağırabiliriz.

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.