Ne zaman mutex kullanmalıyız ve ne zaman semafor kullanmalıyız?
Ne zaman mutex kullanmalıyız ve ne zaman semafor kullanmalıyız?
Yanıtlar:
Neyi ne zaman kullanacağımı işte böyle hatırlıyorum -
Semafor: Uyumak istediğinizde (iş parçacığı) başka bir iş parçacığı size uyanmanızı söyleyene kadar bir semafor kullanın. Semafor 'aşağı' bir iş parçacığında (üretici) olur ve semafor 'yukarı' (aynı semafor için) başka bir iş parçacığında (tüketici) olur örn: Üretici-tüketici probleminde, üretici en az bir tampon yuvası boşalana kadar uyumak ister - yalnızca tüketici iş parçacığı bir arabellek yuvasının ne zaman boş olduğunu söyleyebilir.
Mutex: Siz (evre) aynı anda başka bir evre tarafından çalıştırılmaması gereken kodu yürütmek istediğinizde bir muteks kullanın. Karşılıklı dışlama 'aşağı' tek iplik ve 'yukarı' Muteksleri olur gerekmektedir daha sonra aynı iş parçacığı olur. Örneğin: Global bağlantılı bir listeden bir düğümü siliyorsanız, siz düğümü silerken başka bir iş parçacığının işaretçilerle uğraşmasını istemezsiniz. Bir muteks edindiğinizde ve bir düğümü silmekle meşgul olduğunuzda, başka bir iş parçacığı aynı muteksi elde etmeye çalışırsa, siz muteksi serbest bırakana kadar uyku moduna geçecektir.
Spinlock: Gerçekten bir muteks kullanmak istediğinizde bir spinlock kullanın, ancak iş parçacığınızın uyumasına izin verilmiyor. Örneğin: İşletim sistemi çekirdeği içindeki bir kesme işleyicisi asla uyumamalıdır. Aksi takdirde sistem donacak / çökecektir. Kesme işleyicisinden küresel olarak paylaşılan bağlantılı listeye bir düğüm eklemeniz gerekirse, bir spinlock edin - düğüm ekle - serbest bırak döndürme kilidi edinin.
Muteks, semafora benzer , ancak bir seferde yalnızca bir dolaba izin veren ve sahiplik kısıtlamaları bir semafordan daha katı olabilen karşılıklı bir dışlama nesnesidir .
Normal bir sayma semaforuna (bir sayı ile) eşdeğer olarak düşünülebilir ve yalnızca onu kilitleyen aynı iş parçacığı tarafından serbest bırakılabilme gereksinimi (a) .
Öte yandan bir semafor, keyfi bir sayıya sahiptir ve aynı anda birçok dolap tarafından kilitlenebilir. Ve onu iddia eden aynı iş parçacığı tarafından serbest bırakılması gerekliliği olmayabilir (ancak, eğer değilse, tahsis edilmiş bellek gibi, şu anda bundan kimin sorumlu olduğunu dikkatlice izlemelisiniz).
Öyleyse, bir kaynağın birkaç örneğine sahipseniz (örneğin, üç teyp sürücüsü), 3 numaralı bir semafor kullanabilirsiniz. Bunun size bu teyp sürücülerinden hangisine sahip olduğunuzu söylemediğini, belirli bir sayı.
Ayrıca semaforlarla, tek bir dolabın bir kaynağın birden fazla örneğini, örneğin bir banttan banda kopyasını kilitlemesi mümkündür. Bir kaynağınız varsa (bozmak istemediğiniz bir bellek konumu söyleyin), bir muteks daha uygundur.
Eşdeğer işlemler şunlardır:
Counting semaphore Mutual exclusion semaphore
-------------------------- --------------------------
Claim/decrease (P) Lock
Release/increase (V) Unlock
Bir kenara: semaforları talep etmek ve yayınlamak için kullanılan tuhaf harfleri hiç merak ettiyseniz, bunun nedeni mucit Hollandalı olmasıdır. Probeer te verlagen denemek ve azaltmak, verhogen ise artırmak demektir.
(a) ... ya da bir semafordan tamamen farklı bir şey olarak düşünülebilir, neredeyse her zaman farklı kullanımları göz önüne alındığında daha güvenli olabilir.
Muteksin 1 numaralı bir semafor olmadığını anlamak çok önemlidir !
İkili semafor gibi şeylerin olmasının nedeni budur (gerçekte 1 numaralı semaforlardır).
Mutex ve İkili Semafor arasındaki fark, sahiplik ilkesidir:
Muteks, bir görev tarafından elde edilir ve bu nedenle aynı görev tarafından da serbest bırakılmalıdır. Bu, ikili semaforlarla ilgili birkaç sorunu çözmeyi mümkün kılar (Yanlış bırakma, özyinelemeli kilitlenme ve öncelikli ters çevirme).
Uyarı: "Bunu mümkün kılar" yazdım, bu sorunların nasıl çözüleceği OS uygulamasına bağlıdır.
Muteksin aynı görev tarafından serbest bırakılması gerektiğinden, görevlerin senkronizasyonu için çok iyi değildir. Ancak koşul değişkenleriyle birleştirilirse, her tür ipc ilkelini oluşturmak için çok güçlü yapı taşları elde edersiniz.
Bu yüzden benim tavsiyem: eğer temiz bir şekilde uygulanmış muteksler ve koşul değişkenleri (POSIX pthreads ile olduğu gibi) varsa bunları kullanın.
Semaforları yalnızca çözmeye çalıştığınız probleme tam olarak uyuyorlarsa kullanın, başka temel öğeler oluşturmaya çalışmayın (örneğin semaforlardan rw kilitleri, bunlar için muteksler ve koşul değişkenleri kullanın)
Çok sayıda yanlış anlaşılan muteks ve semafor var. Şimdiye kadar bulduğum en iyi açıklama bu 3 Bölümlü makalede:
Muteks ve Semaforlar - Bölüm 1: Semaforlar
Mutex ve Semaforlar - Bölüm 2: Muteks
Muteks ve Semaforlar - Bölüm 3 (son kısım): Karşılıklı Dışlama Sorunları
@Opaxdiablo cevabı tamamen doğru olsa da, her ikisinin de kullanım senaryosunun oldukça farklı olduğunu belirtmek isterim. Muteks, kod parçalarının eşzamanlı olarak çalışmasını önlemek için kullanılır, semaforlar bir iş parçacığının başka bir iş parçacığının çalışması için sinyal vermesi için kullanılır.
/* Task 1 */
pthread_mutex_lock(mutex_thing);
// Safely use shared resource
pthread_mutex_unlock(mutex_thing);
/* Task 2 */
pthread_mutex_lock(mutex_thing);
// Safely use shared resource
pthread_mutex_unlock(mutex_thing); // unlock mutex
Semafor senaryosu farklıdır:
/* Task 1 - Producer */
sema_post(&sem); // Send the signal
/* Task 2 - Consumer */
sema_wait(&sem); // Wait for signal
Daha fazla açıklama için http://www.netrino.com/node/202 adresine bakın.
sema_wait
:-) Bence ikisi de kaynaklarla ilgili ve diğer konulara verilen bildirim, bir yan etkidir (çok önemli, performans açısından) koruma.
You say that the usage pattern of semaphores is to notify threads
Konuları bildirmekle ilgili bir nokta. Sen diyebilirsin sem_post
güvenle bir sinyal işleyici (dan pubs.opengroup.org/onlinepubs/009695399/functions/... ) ama çağrısına tavsiye edilmez pthread_mutex_lock
ve pthread_mutex_unlock
(sinyal eylemcilerden manpages.ubuntu.com/manpages/lucid/man3/... )
Bkz. "Tuvalet Örneği" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm :
Karşılıklı dışlama:
Tuvaletin anahtarıdır. Bir kişi o anda anahtarı alabilir - tuvaleti kullanabilir -. Bittiğinde, kişi anahtarı sıradaki bir sonraki kişiye verir (serbest bırakır).
Resmi olarak: "Muteksler tipik olarak, birden fazla iş parçacığı tarafından eşzamanlı olarak yürütülemeyen yeniden giriş kodunun bir bölümüne erişimi serileştirmek için kullanılır. Bir muteks nesnesi, yalnızca bir iş parçacığının kontrollü bir bölüme girmesine izin vererek, erişim sağlamaya çalışan diğer iş parçacıklarını zorlar. o bölüm, o bölümden ilk iş parçacığı çıkana kadar beklemek için. " Ref: Symbian Geliştirici Kitaplığı
(Muteks gerçekte değeri 1 olan bir semafordur.)
Semafor:
Ücretsiz özdeş tuvalet anahtarlarının sayısıdır. Örneğin, aynı kilitleri ve anahtarları olan dört tuvaletimiz olduğunu varsayalım. Semafor sayısı - anahtar sayısı - başlangıçta 4'e ayarlanır (dört tuvaletin tümü ücretsizdir), o zaman insanlar içeri girdikçe sayma değeri azalır. Tüm tuvaletler doluysa, yani. sol serbest anahtar yok, semafor sayısı 0'dır. Şimdi, eq. bir kişi tuvaleti terk eder, semafor 1'e çıkarılır (bir ücretsiz anahtar) ve sıradaki diğer kişiye verilir.
Resmi olarak: "Bir semafor, paylaşılan bir kaynağın eşzamanlı kullanıcılarının sayısını maksimum bir sayıya kadar sınırlar. İş parçacıkları, kaynağa erişim talep edebilir (semaforu azaltarak) ve kaynağı kullanmayı bitirdiklerini (semaforu artırarak) işaret edebilir. " Ref: Symbian Geliştirici Kitaplığı
Kulağa çılgınca gelmemeye çalışıyorum ama kendime engel olamıyorum.
Sorunuz muteks ve semaforlar arasındaki fark nedir? Daha kesin olmak gerekirse, 'muteks ve semaforlar arasındaki ilişki nedir?' Olmalıdır.
(Bu soruyu ekleyebilirdim, ancak% 100 eminim ki aşırı hevesli bir moderatör, farklılık ve ilişki arasındaki farkı anlamadan onu tekrar olarak kapatır.)
Nesne terminolojisinde şunu gözlemleyebiliriz:
gözlem.1 Semafor muteks içerir
observation.2 Mutex semafor değildir ve semafor muteks değildir.
İkili semaforlar olarak adlandırılan, muteksmiş gibi davranan bazı semaforlar vardır, ancak bunlar muteks DEĞİLDİR.
Muteksten bir Semafor yapmak için gerekli olan Signaling (posix bu isim için condition_variable kullanır) adında özel bir bileşen vardır. Bunu bir bildirim kaynağı olarak düşünün. İki veya daha fazla iş parçacığı aynı bildirim kaynağına abone ise, uyandırmaları için onları BİRİNE veya TÜMÜNÜ mesaj göndermek mümkündür.
Muteks tarafından korunan semaforlarla ilişkili bir veya daha fazla sayaç olabilir. Semafor için en basit senaryo, 0 veya 1 olabilen tek bir sayaç vardır.
Muson yağmuru gibi karışıklığın aktığı yer burasıdır.
Sayacı 0 veya 1 olabilen semafor muteks DEĞİLDİR.
Mutex'in iki durumu (0,1) ve bir sahipliği (görev) vardır. Semaforun bir muteksi, bazı sayaçları ve bir koşul değişkeni vardır.
Şimdi, hayal gücünüzü kullanın ve sayaç kullanımının her kombinasyonu ve ne zaman sinyal verileceği tek bir tür Semafor yapabilir.
0 veya 1 değerine sahip tek sayaç ve değer 1'e gittiğinde sinyal verir VE ardından sinyali bekleyen adamlardan birinin kilidini açar == İkili semafor
Değeri 0 ile N arasında olan ve değer N'den küçük olduğunda sinyal veren tek sayaç ve değerler N == Sayma semaforu olduğunda kilitler / bekler
Değeri 0 ila N olan ve değer N'ye gittiğinde sinyal veren tek sayaç ve değerler N == Bariyer semaforundan küçük olduğunda kilitler / bekler (eğer çağırmazlarsa, yapmaları gerekir.)
Şimdi sorunuza gelince, ne zaman kullanılmalı? (VEYA daha doğrusu soru version.3 ne zaman muteks ve ne zaman ikili-semafor kullanılmalıdır, çünkü ikili olmayan semaforla karşılaştırma yoktur.) 1. ikiliyle sağlanmayan özelleştirilmiş bir davranış istediğinizde muteks kullanın. semafor, spin-lock veya fast-lock veya recursive-lock'lardır. Muteksleri genellikle özniteliklerle özelleştirebilirsiniz, ancak semaforu özelleştirmek yeni semafor yazmaktan başka bir şey değildir. 2. Hafif VEYA daha hızlı ilkel istiyorsunuz
Ne istediğinizi tam olarak sağladığında semaforları kullanın.
İkili semafor uygulamanızın ne sağladığını anlamıyorsanız, IMHO, mutex'i kullanın.
Ve son olarak sadece SO'ya güvenmek yerine bir kitap okuyun.
Bence soru muteks ve ikili semafor arasındaki fark olmalı.
Mutex = Bir sahiplik kilit mekanizmasıdır, sadece kilidi alan iş parçacığı kilidi açabilir.
binary Semaphore = Daha çok bir sinyal mekanizmasıdır, diğer yüksek öncelikli herhangi bir iş parçacığı istenirse sinyal verebilir ve kilidi alabilir.
Mutex, paylaşılan kaynağı korumaktır.
Semafor, konuları dağıtmaktır.
Mutex: Satılacak
bazı biletlerin olduğunu hayal edin. Birçok kişinin aynı anda biletleri satın aldığı bir durumu simüle edebiliriz: her kişi bilet satın almak için bir iş parçacığıdır. Açıkçası, biletleri korumak için muteksi kullanmamız gerekiyor çünkü bu paylaşılan kaynaktır.
Semafor:
Aşağıdaki gibi bir hesaplama yapmamız gerektiğini düşünün:
c = a + b;
Ayrıca, geta()
hesaplanacak bir işleve , hesaplanacak a
bir işleve getb()
ve hesaplamayı yapacak b
bir işleve getc()
ihtiyacımız var c = a + b
.
Açıkçası, c = a + b
bitmedikçe geta()
ve getb()
bitmemişse yapamayız .
Üç işlev üç iş parçacığı ise, üç iş parçacığını göndermemiz gerekir.
int a, b, c;
void geta()
{
a = calculatea();
semaphore_increase();
}
void getb()
{
b = calculateb();
semaphore_increase();
}
void getc()
{
semaphore_decrease();
semaphore_decrease();
c = a + b;
}
t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);
Semaforun yardımıyla, yukarıdaki kod t3
bunun işini yapmayacağından emin olabilir t1
vet2
işlerini yapmış.
Kısacası, semafor, iş parçacıklarının mantıksal bir sıra olarak yürütülmesini sağlamaktır, muteks ise paylaşılan kaynağı korumaktır.
Bu yüzden, bazı insanlar muteksin her zaman 1 başlangıç değerine sahip özel bir semafor olduğunu söylese bile, bunlar aynı şey DEĞİLDİR. Yapabilseniz bile birini diğeriyle değiştirmeyin.
x = getx(); y = gety(); z = x + y;
biz yapamaz çünkü Nedense, biz üç şey yapmak için üç konuları kullanın şimdi parçacığı sırası çok önemlidir x + y
sürece getx
ve gety
bitirdim. Kısacası, semafor, çoklu iş parçacığının yürütülme sırasını önemsediğimizde kullanılır.
x
ve y
tamamlanana kadar bekleyin , sonra hesaplayın diyebilirim z = x + y
. Java'nın olduğunu biliyorum CyclicBarrier
. Ayrıca, mapreduce
semafor kullanım durumu da diyebilir miyim emin değilim , çünkü reduce
tüm map
s tamamlanana kadar yapamam .
Yukarıdaki cevapların tümü iyi kalitede, ancak bu sadece ezberlemek için. Mutex adı Karşılıklı Dışlayıcı'dan türetilmiştir, bu nedenle bir muteks kilidi, her seferinde yalnızca bir tanesinde olduğu gibi ikisi arasında Karşılıklı Dışlama olarak düşünmeye motive olursunuz ve eğer ben sahip olsaydınız, ancak ben serbest bıraktıktan sonra sahip olabilirsiniz. Öte yandan, Semafor için böyle bir durum mevcut değildir , tıpkı bir trafik sinyali gibidir (Semafor kelimesi de aynı anlama gelir).
Belirtildiği gibi, bir sayıya sahip bir semafor, bir muteks ile aynı şey olan 'ikili' bir semafor ile aynı şeydir.
Kullanılandan daha büyük bir sayıya sahip semaforları gördüğüm ana şeyler, belirli bir sabit büyüklükte bir sıraya sahip olduğunuz üretici / tüketici durumlarıdır.
O halde iki semaforunuz var. İlk semafor başlangıçta kuyruktaki öğelerin sayısı olacak şekilde ayarlanır ve ikinci semafor 0'a ayarlanır. Üretici ilk semaforda bir P işlemi yapar ve kuyruğa ekler. ve saniyede bir V işlemi yapar. Tüketici, ikinci semaforda bir P işlemi yapar, kuyruktan çıkarır ve ardından ilkinde bir V işlemi yapar.
Bu şekilde, yapımcı kuyruğu her doldurduğunda engellenir ve sıra boş olduğunda tüketici bloke edilir.
Muteks, semaforun özel bir durumudur. Bir semafor, birkaç iş parçacığının kritik bölüme girmesine izin verir. Bir semafor oluştururken kritik bölümde iş parçacıklarına nasıl izin verileceğini tanımlarsınız. Elbette kodunuz bu kritik bölüme birkaç erişimi idare edebilmelidir.
İkili semafor ve Mutex farklıdır. İşletim sistemi perspektifinden, bir ikili semafor ve sayma semaforu aynı şekilde uygulanır ve bir ikili semafor 0 veya 1 değerine sahip olabilir.
Mutex -> Kodun kritik bir bölümü için yalnızca bir ve tek karşılıklı dışlama amacıyla kullanılabilir.
Semafor -> Çeşitli problemleri çözmek için kullanılabilir. İkili semafor sinyal vermek için kullanılabilir ve ayrıca karşılıklı dışlama problemini çözebilir. 0 olarak başlatıldığında sinyal sorununu çözer ve 1 olarak başlatıldığında karşılıklı dışlama sorununu çözer .
Kaynak sayısı daha fazla olduğunda ve senkronize edilmesi gerektiğinde, sayma semaforunu kullanabiliriz.
Blogumda bu konuları detaylı bir şekilde tartıştım.
https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html