Ne zaman mutex kullanmalıyız ve ne zaman semafor kullanmalıyız


Yanıtlar:


93

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.


1
eklemek için: semaforlar ve muteks, senkronizasyon sağlamanın iki yoludur. semafor, daha çok sinyalleşme ile ilgili olabilir (örneğin, üretici ve tüketici problem senaryosu) ve muteks, bir seferde bir tanesine erişime izin vermekle daha fazla ilgili olabilir (paylaşılan kaynağa erişmek için birkaç istek, ancak bir seferde yalnızca bir tane verilir). [güzel makale: geeksforgeeks.org/mutex-vs-semaphore/]
parasrish

57

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.


Tamam, ben de ikili semafora rastladım. İkili semafor için ne zaman girmemiz gerekir ve ne zaman muteks kullanmalıyız?
Karthik Balaguru

Kavramsal olarak, bir ikili semafor olan bir mutex ve bunun tek sayımı ile normal semafora eşittir. Verimlilik veya kaynağın sahipliği gibi kavramın uygulamalarında farklılıklar olabilir (BTW ile aynı fikirde olmadığım hükmün dışında biri tarafından serbest bırakılabilir - bir kaynak yalnızca onu iddia eden iş parçacığı tarafından serbest bırakılabilir. ).
paxdiablo

1
Diğer bir potansiyel uygulama farkı, özyinelemeli muteks. Yalnızca bir kaynak olduğu için, tek bir iş parçacığının onu birden çok kez kilitlemesine izin verilebilir (bu kadar çok kez serbest bıraktığı sürece). Birden çok örnekli bir kaynakla bu o kadar kolay değildir, çünkü iş parçacığının hak talebinde bulunup bulunmadığını bilmiyor olabilirsiniz başka bir örneği mi yoksa aynı örneği tekrar .
paxdiablo

1
Belirli bir sorunu çözerler. Çözdükleri sorunun çözmeyen insanlar olduğu gerçeğiÇözdükleri anlamıyla muteks olması, çözümü hiçbir şekilde küçümsememelidir :-)
paxdiablo

5
Bir muteks, ikili bir semafordan tamamen farklıdır. Üzgünüm ama bu tanım yanlış
Peer Stritzinger

49

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ı


Bu sitenin url'leri acayip karakterler içeriyor ve bu yüzden çalışmıyor ... Üzerinde çalışıyorum
Peer Stritzinger

13

@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.


2
Haklısın. Bir numaralı semafor kullanıyor olsanız bile, yaptığınız şeyle ilgili bir muteks kullanmanıza kıyasla bir şeyi ima ediyorsunuz.
Omnifarious

Buna katılmadığımdan emin değilim, ama o kadar şiddetle katılmıyorum ki size olumsuz oy vereceğim :-) Semaforların kullanım modelinin iş parçacıklarını bildirmek olduğunu söylüyorsunuz, ancak mutekslerin bekleyen başka bir iş parçacığı olduğunda tam olarak yaptığı şey bu üzerinde, ve tam olarak semaforlar içinde parçacığı olmadığında ne yapmazsema_wait :-) Bence ikisi de kaynaklarla ilgili ve diğer konulara verilen bildirim, bir yan etkidir (çok önemli, performans açısından) koruma.
paxdiablo

You say that the usage pattern of semaphores is to notify threadsKonuları bildirmekle ilgili bir nokta. Sen diyebilirsin sem_postgüvenle bir sinyal işleyici (dan pubs.opengroup.org/onlinepubs/009695399/functions/... ) ama çağrısına tavsiye edilmez pthread_mutex_lockve pthread_mutex_unlock(sinyal eylemcilerden manpages.ubuntu.com/manpages/lucid/man3/... )

@paxdiablo: Bu muteks ikili semafor arasında önemli bir fark var, referans sayısını korumak. Mutex veya herhangi bir koşullu muteksin kilit ile ilgili herhangi bir sayım tutmadığını söyleyebiliriz, burada sayımı sürdürmek için sempahore kullanılır. Yani sem_wait ve sem_post sayımı sürdürüyor.
Prak

9

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ığı


7

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.

  1. 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

  2. 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

  3. 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.


5

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.


5

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 abir işleve getb()ve hesaplamayı yapacak bbir işleve getc()ihtiyacımız var c = a + b.

Açıkçası, c = a + bbitmedikç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 t3bunun işini yapmayacağından emin olabilir t1vet2 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.


Bilet satmak güzel bir örnek. semafor örneği biraz belirsizdir (yine de bana göre).
duaagupd

1
@prayagupd Semafor örneği, bir sıra ile iş parçacığı yapmaktır, oysa bilet satmak için herhangi bir sipariş gerekmez. Üç kişi varsa: a, b ve c. Bilet almaya geldiklerinde, bilet alma sırasını hiç umursamıyoruz. Biz böyle bir hesaplama yaparsak Ancak: 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 + ysürece getxve getybitirdim. Kısacası, semafor, çoklu iş parçacığının yürütülme sırasını önemsediğimizde kullanılır.
Yves

yakaladım seni. Bu benzer sesler bariyer . İş parçacıkları tamamlanana xve ytamamlanana kadar bekleyin , sonra hesaplayın diyebilirim z = x + y. Java'nın olduğunu biliyorum CyclicBarrier. Ayrıca, mapreducesemafor kullanım durumu da diyebilir miyim emin değilim , çünkü reducetüm maps tamamlanana kadar yapamam .
duaagupd

@prayagupd Evet. Bunu söyleyebilirsin.
Yves

2

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).


1

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.


1

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.


-1

İ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

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.