it-swarm-tr.com

İkili semafor ve muteks arasındaki fark

İkili bir semafor ile muteks arasında bir fark var mı, yoksa esas olarak aynı mı?

741
Nitin

OnlarDEĞILaynı şeydir. Farklı amaçlar için kullanılıyorlar!
Her iki semafor türü boş/dolu bir duruma sahipken ve aynı API'yi kullanırken, kullanımları çok farklıdır.

Karşılıklı Dışlama Semaforları
Karşılıklı Dışlama semaforları, paylaşılan kaynakları (veri yapısı, dosya vb.) Korumak için kullanılır.

Bir Mutex semaforu, onu alan göreve "aittir". Görev B, halihazırda Görev A tarafından tutulan bir muteksi göstermeye çalışırsa, Görev B'nin çağrısı bir hata döndürür ve başarısız olur.

Mutexes her zaman aşağıdaki sırayı kullanır:

 - SemTake 
 - Kritik Bölüm 
 - SemGive

İşte basit bir örnek:

 Konu A Konu B 
 Mutex atın 
 Erişim verisi 
 ... Mutex atın <== 
 ... 
 Mutex'e erişim verisi verin <== 
 ... 
 Engelini Kaldır 

İkili Semafor
İkili Semafor tamamen farklı bir soruyu ele alıyor:

  • Görev B, bir şeyin olmasını beklemektedir (örneğin bir sensör tetiklenir).
  • Sensör Açma ve Kesme Hizmeti Rutini çalışır. Gezinin bir görevini bildirmesi gerekiyor.
  • Görev B çalışmalı ve sensör hareketi için uygun işlemleri yapmalıdır. O zaman beklemeye geri dön.

   Task A                      Task B
   ...                         Take BinSemaphore   <== wait for something
   Do Something Noteworthy
   Give BinSemaphore           do something    <== unblocks

İkili bir semaforla, B'nin semafor almasının ve A'nın vermesinin tamam olduğunu not edin.
Yine, ikili bir semafor bir kaynağı erişimden korumaz. Bir semafor alma ve verme eylemi temelde çözülür.
Genellikle aynı görevin aynı ikili semafor için vermesi ve alması aynı anlama gelmez.

635
Benoit

Tuvalet örneği eğlenceli bir benzetmedir:

Karşılıklı dışlama:

Bir tuvaletin anahtarı. Bir kişi anahtarı alabilir - tuvaleti işgal eder - o zaman. Tamamlandığında, kişi sıradaki sıradaki kişiye anahtarı verir (serbest bırakır).

Resmi olarak: "Mutex'ler genellikle birden fazla iş parçacığı tarafından aynı anda yürütülemeyen bir yeniden giriş kodunun bir bölümüne erişimi seri hale getirmek için kullanılır. Bir mutex nesnesi yalnızca bir iş parçacığının denetlenen bir bölüme girmesine izin verir ve diğer iş parçacıklarına erişmeye çalışır bu bölüm, ilk bölüm o bölümden çıkana kadar bekleyecek. " Ref: Symbian Geliştirici Kütüphanesi

(Bir muteks gerçekten 1 değeri olan bir semafordur.)

Semafor:

Ücretsiz aynı tuvalet anahtarı sayısıdır. Örneğin, aynı kilit ve anahtarlara sahip dört tuvaletimiz olduğunu söyleyin. Semafor sayımı - anahtarların sayısı - başlangıçta 4 olarak ayarlanır (dört tuvaletin tamamı ücretsizdir), o zaman sayılar insanlar gelirken azalır. Tüm tuvaletler doluysa, yani. boş anahtar kalmamış, semafor sayısı 0'dır. Şimdi, eq. bir kişi tuvaleti terk eder, semafor 1 (bir serbest anahtar) 'a çıkarılır ve sırada bir sonraki kişiye verilir.

Resmen: "Bir semafor, paylaşılan bir kaynağın eşzamanlı kullanıcılarının sayısını maksimum sayıya kadar sınırlar. Konular kaynağa erişim talep edebilir (semaforu azaltarak) ve kaynağı kullanarak bitirdiklerini işaret edebilir (semaforu artırarak). " Ref: Symbian Geliştirici Kütüphanesi

416
dlinsin

Mutex, yalnızca onu edinen iş parçacığı tarafından serbest bırakılabilir, semaforu başka bir iş parçacığından (ya da işleminden) işaret edebilirsiniz, bu nedenle semaforlar üretici-tüketici gibi bazı senkronizasyon problemleri için daha uygundur.

Windows'ta ikili semaforlar, mutekslerden çok olay nesneleri gibidir.

411
Mladen Janković

Konuyla ilgili güzel makaleler:

2. bölümden:

Muteks, ikili semaforun prensiplerine benzer bir farkla benzerdir: mülkiyet prensibi. Sahiplik, bir görev bir muteksi kilitlediğinde (edindiğinde) yalnızca kilidini açabileceği (serbest bırakabileceği) basit bir kavramdır. Bir görev bir muteksin kilidini açmaya çalışırsa, kilitlenmemiş (bu nedenle kendi kendine ait değildir) bir hata koşuluyla karşılaşılır ve en önemlisi mutex'in kilidi açılmaz. Karşılıklı dışlama nesnesinin mülkiyeti yoksa, ne denildiğine bağlı olarak, bir muteks değildir.

139
teki

Yukarıdaki cevapların hiçbiri karmaşayı gideremediğinden, işte benim kafamı temizleyen bir cevap var.

Kesinlikle, bir muteks bir kaynağa erişimi senkronize etmek için kullanılan bir kilitleme mekanizmasıdır . Yalnızca bir görev (işletim sistemi soyutlamasına dayalı bir iş parçacığı ya da işlemi olabilir) muteks alabilir. Bu, mutex ile ilişkilendirilmiş bir mülkiyet olacağı anlamına gelir ve yalnızca sahibi kilidi (mutex) serbest bırakabilir.

Semafor sinyal mekanizmasıdır (“Yaptım, devam edebilirsin” türünde bir sinyal). Örneğin, cep telefonunuzda şarkılar dinliyorsanız (tek bir görev olarak kabul ederseniz) ve aynı zamanda arkadaşınız sizi aradıysa, bir kesme hizmeti rutininin (ISR) çağrı işleme görevini uyandırması için sinyal göndereceği bir kesme tetiklenir .

Kaynak: http://www.geeksforgeeks.org/mutex-vs-semaphore/

92
Hemant

Senkronizasyon semantikleri çok farklı:

  • mutexes belirli bir kaynağa erişimin seri hale getirilmesine izin verir, yani çoklu iş parçacığı bir defada bir kilit bekler ve daha önce belirtildiği gibi owns lock işlemi bitene kadar: sadece this belirli bir iplik kilidini açabilir.
  • ikili semafor, 0 ve 1 değerine sahip bir sayaçtır: herhangi bir görevi bir sem_post yapana kadar onu engelleyen bir görevdir. Semafor bir kaynağın mevcut olduğunu bildirir ve mevcut olduğu bildirilene kadar beklemesini sağlayan mekanizma sağlar.

Görüldüğü gibi, bir muteksi görevden görevlere geçen bir belirteç, kırmızı trafik ışığı gibi bir semafor görebilir (bu, sinyaller.

37
ppi
  • A Mutex , tanım gereği, birden fazla iş parçacığı tarafından aynı anda yürütülemeyen bir yeniden giriş kodunun bir bölümüne erişimi seri hale getirmek için kullanılır.

  • A Semafor , tanım olarak, paylaşılan bir kaynağın eşzamanlı kullanıcılarının sayısını maksimum sayıya kadar sınırlar

  • Bir semafor Mutex olabilir, ancak bir Mutex asla semafor olamaz. Bu basitçe, bir ikili semaforun Mutex olarak kullanılabileceği anlamına gelir, ancak bir Mutex asla semaforun işlevselliğini sergileyemez.

  • Hem semaforlar hem de Mutex (en azından en son çekirdeğin üstünde), doğada münzevi değildir.
  • Hiç kimse semafor sahibi değildir, oysa Mutex'in mülkiyeti ve sahiplerinden sorumlu tutulması. Bu hata ayıklama bakış açısından önemli bir ayrımdır.
  • Mutex durumunda, Mutex’in sahibi olan konu, onu serbest bırakmaktan sorumludur. Ancak, semafor durumunda, bu şart gerekli değildir. Başka bir iş parçacığı s m p s (function.e_ot) kullanarak semafor serbest bırakmak için sinyal verebilir.

  • Geliştiriciler için önemli olan bir başka fark ise semaforların sistem genelinde olması ve aksi temizlenmediği sürece dosya sistemindeki dosyalar biçiminde kalmasıdır. Mutex, işlem genelindedir ve bir işlem sona erdiğinde otomatik olarak temizlenir.

  • Semaforların doğası, bunları dişler arasında olduğu kadar ilişkili ve ilgisiz süreçlerin senkronize edilmesinde de kullanılmasını mümkün kılar. Mutex sadece dişler arasında ve en fazla ilgili işlemler arasında eşitleme yapmak için kullanılabilir (en son çekirdeğin baskı uygulaması, Mutex'in işlem arasında kullanılmasını sağlayan bir özellik ile birlikte gelir).
  • Çekirdek belgelerine göre, Mutex semaforlarla karşılaştırıldığında daha hafiftir. Bunun anlamı, semafor kullanımına sahip bir programın, Mutex'e sahip olan bir programa kıyasla daha yüksek bir bellek ayak izine sahip olmasıdır.
  • Bir kullanım açısından bakıldığında, Mutex, semaforlara kıyasla daha basit bir semantiye sahiptir.
35
Varun Chhangani

Teorik düzeyde, anlamsal olarak farklı değillerdir. Bir muteks kullanarak semafor veya tersi uygulayabilirsiniz (örneğin, burada ). Uygulamada, uygulama farklıdır ve biraz farklı hizmetler sunarlar.

Pratik fark (onları çevreleyen sistem hizmetleri açısından), bir muteksin uygulanmasının daha hafif bir senkronizasyon mekanizması olmayı hedeflemesidir. Oracle-speak, mutexes latches , semaforlar bekler olarak bilinir.

En düşük seviyede, bir tür atomik test ve set mekanizması kullanırlar. Bu, bir bellek konumunun geçerli değerini okur, bir tür koşullu hesaplar ve o konumdaki bir değeri, kesilemez olan tek bir komutla yazar. Bu, sizden önce başkasının olup olmadığını görmek için bir muteks edinip test edebileceğiniz anlamına gelir.

Tipik bir muteks uygulamasında, test et ve ayarla komutunu uygulayan ve mutex'i başka bir şeyin ayarlayıp ayarlamadığını değerlendiren bir işlem ya da iş parçacığı vardır. Buradaki kilit nokta, zamanlayıcı ile etkileşimin olmadığı, bu yüzden kilidi ayarlayan hiçbir fikrimiz (ve umrumuzda değil). Sonra zaman dilimimizi keseriz ve görev yeniden planlandığında tekrar deneriz veya bir döndürme kilidi gerçekleştiririz. Döndürme kilidi aşağıdaki gibi bir algoritmadır:

Count down from 5000:
     i. Execute the test-and-set instruction
    ii. If the mutex is clear, we have acquired it in the previous instruction 
        so we can exit the loop
   iii. When we get to zero, give up our time slice.

Korumalı kodumuzu çalıştırmayı bitirdiğimizde ( kritik bölüm olarak bilinir) mutex değerini sıfıra ya da 'temiz' anlamına gelir. Birden fazla görev muteks almaya çalışıyorsa, bunlar mutex serbest bırakıldıktan sonra zamanlanacak olan sonraki görev kaynağa erişir. Genelde, ortak bir veri yapısında güncelleme yapmak için, yalnızca çok kısa bir süre için özel erişimin gerekli olduğu senkronize bir kaynağı kontrol etmek için muteksleri kullanırsınız.

Bir semafor, sayıcı olan ve zamanlayıcı ile etkileşime giren bazı sistem çağrısı sarmalayıcılarına sahip olan ve genellikle muteks kitaplıklarından biraz daha derinlemesine sahip olan bir senkronize veri yapısıdır (tipik olarak bir muteks kullanarak). Semaforlar artırılır ve azaltılır ve başka bir şey hazır olana kadar blok görevlerine kullanılır. Bunun basit bir örneği için Üretici/Tüketici Sorunu bölümüne bakın. Semaforlar bir değere başlatılır - bir ikili semafor sadece semaforun 1 olarak başlatıldığı özel bir durumdur. Bir semafor göndermek, bekleme sürecini uyandırma etkisine sahiptir.

Temel bir semafor algoritması şöyle görünür:

(somewhere in the program startup)
Initialise the semaphore to its start-up value.

Acquiring a semaphore
   i. (synchronised) Attempt to decrement the semaphore value
  ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.

Posting a semaphore
   i. (synchronised) Increment the semaphore value
  ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.  
 iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.

İkili bir semafor durumunda, ikisi arasındaki temel pratik fark, gerçek veri yapısını çevreleyen sistem hizmetlerinin niteliğidir.

EDIT: Evan'ın doğru bir şekilde işaret ettiği gibi, spinlocklar tek bir işlemci makinesini yavaşlatır. Çok işlemcili bir kutuda sadece bir spinlock kullanırsınız, çünkü tek bir işlemcide mutex'i tutan işlem başka bir görev çalışırken onu asla sıfırlamaz. Spinlocklar sadece çok işlemcili mimarilerde faydalıdır.

Mutex ve semaforlar senkronizasyon ilkelleri olarak kullanılsa da, aralarında büyük bir fark vardır. Mutex durumunda, sadece mutex'i kilitleyen ya da edinen iş parçacığı kilidini açabilir. Bir semafor durumunda, bir semaforda bekleyen bir iplik, farklı bir iplik ile işaretlenebilir. Bazı işletim sistemleri işlem arasında muteks ve semaforların kullanılmasını destekler. Genellikle kullanım paylaşılan hafızada yaratıyor.

18
Praveen_Shukla

Mutex: T1'in kritik bölüm iş parçacığına sahip olduğumuzu varsayalım ve sonra aşağıdaki adımları takip edin. T1:

  1. Kilit
  2. Kritik Bölümü Kullan
  3. Kilidini aç

İkili semafor: Sinyal beklemeye ve sinyale dayanarak çalışır. wait (s) "s" değerini genellikle bir azalır "s" değeri "1" değeriyle başlar, sinyal (ler) "s" değerini birer artırır. "s" değeri 1 ise, hiç kimse kritik bölümü kullanmıyorsa, değer 0 olduğunda kritik bölüm kullanımda demektir. Diyelim ki iplik T2 kritik bölümü kullanıyorsa aşağıdaki adımları takip eder. T2:

  1. wait (s) // başlangıçta s değeri çağrıldıktan sonra birdir bekleyin, değeri bir azalır, yani 0
  2. Kritik bölüm kullan
  3. sinyal (ler) // şimdi s değeri arttırıldı ve 1 oldu

Mutex ve Binary semafor arasındaki ana fark, iş parçacığının kritik bölümü kilitlemesi durumunda Mutext'tedir, sonra kritik bölümün kilidini açmak zorunda kalır, başka hiçbir konunun kilidini açamaz, ancak eğer bir iş parçacığı bekleme (ler) işlevini kullanarak kritik bölümü kilitlerse Binary semafor durumunda değer s "0" olur ve hiç kimse "s" nin değeri 1 olana kadar erişemez, ancak bazı diğer konu çağrıları sinyal (ler) inin ardından "s" nin değerinin 1 olacağı ve diğer fonksiyonların kritik bölüm kullanmasına izin verdiğini varsayalım. Bu nedenle İkili semafor iş parçacığında sahipliği yoktur.

11
Sumit Naik

Bir iş parçacığındaki verileri aynı anda başka bir iş parçacığı tarafından erişilen bir veri kilitlemek için mutex kullandığınız açıkça. Az önce lock() olarak adlandırdığınızı ve verilere erişme sürecinde olduğunuzu varsayalım. Bu, başka bir iş parçacığının (veya aynı iş parçacığı kodunun başka bir örneğinin) aynı muteks tarafından kilitlenmiş aynı verilere erişmesini beklemeyeceğiniz anlamına gelir. Yani, aynı iş parçacığı kodu farklı bir iş parçacığı örneğinde çalıştırılıyorsa, kilidi vurur, sonra lock() orada kontrol akışını engellemelidir. Bu, aynı verilere erişen ve aynı muteks tarafından kilitlenen farklı bir iş parçacığı kodu kullanan bir iş parçacığı için de geçerlidir. Bu durumda, hala verilere erişme sürecindesiniz ve örneğin, mutex kilidini açmak için başka 15 saniye sürebilir (böylece, mutex kilidinde engellenen diğer iş parçacığının engellenmesi ve denetimin engellenmesine izin vermesi için) verilere eriş). Ne pahasına olursa olsun, başka bir iş parçacığının aynı muteksin kilidini açmasına izin veriyor ve sırayla, muteks kilidinde zaten bekleyen (engelleme) iş parçacığının verilerin engellenmesine ve erişmesine izin veriyor musunuz? Umarım burada ne dediğimi aldınız? Evrensel tanım konusunda anlaşmaya varıldığı gibi !,

  • “mutex” ile bu olamaz. Başka hiçbir diş, dişinizde kilidin kilidini açamaz
  • “ikili semafor” ile bu olabilir. Başka bir diş, dişinizdeki kilidi açabilir

Bu nedenle, muteks yerine ikili semafor kullanma konusunda çok titizseniz, kilitleri ve kilidini “kapsamayı” çok dikkatli olmalısınız. Yani, her kilidi kilitleyen her kontrol akışının kilit açma aramasına basması gerekir, ayrıca “ilk kilit açma” olmamalı, bunun yerine daima “ilk kilit” olmalıdır.

10
paxi

Mutex "Kilitleme Mekanizmaları" için kullanılır. bir seferde bir işlem paylaşılan bir kaynak kullanabilir

buna karşılık

Semaforlar "Sinyalleme Mekanizmaları" için "Yaptım, şimdi devam edebilir" gibi

10
Jamshad Ahmad

Windows'ta, mutekslerle ikili semafor arasında iki fark vardır:

  1. Bir muteks yalnızca sahipliği olan iş parçacığı, yani daha önce Bekleme işlevi olarak adlandırılan iş parçacığı tarafından serbest bırakılabilir (ya da oluştururken sahiplik aldı). Bir semafor herhangi bir iş parçacığı tarafından serbest bırakılabilir.

  2. Bir iş parçacığı engelleme olmadan bir muteks üzerinde art arda bekleme işlevini çağırabilir. Bununla birlikte, aralarında semafor serbest bırakmadan ikili bir semafor üzerinde iki kez bir bekleme işlevi çağırırsanız, iplik engellenir.

10
Rich

Efsane:

Birkaç makale "ikili semafor ve muteks aynı" ya da "1 değeri olan semafor muteks" diyor, ancak temel fark Mutex, ancak edinilen iş parçacığı tarafından semaforu başka bir iş parçacığından gelen sinyallerle serbest bırakabiliyor.

Anahtar noktaları:

• Bir iplik birden fazla kilit alabilir (Mutex).

• Bir muteks birden fazla defa kilitlenebilir, ancak özyinelemeli bir muteks ise, burada muteks için kilitleme ve kilit açma aynı olmalıdır.

• Bir muteksi zaten kilitlemiş olan bir iş parçacığı, muteksi tekrar kilitlemeye çalışırsa, bu muteksin kilitlenme listesine neden olan bekleme listesine girecektir.

• İkili semafor ve muteks benzerdir ancak aynı değildir.

• Mutex, kendisiyle ilişkili koruma protokolleri nedeniyle maliyetli bir işlemdir.

• Mutex'in asıl amacı, atomik erişim sağlamak veya kaynaklara kilitlenmektir.

9
Saurabh Sinha

A Mutex / paylaşılan tek bir kaynağa erişimi kontrol eder. Bu kaynağa edinme () erişimine ve release () işlemlerine işlem yapılmasını sağlar.

A Semafor paylaşılan bir kaynak havuzuna erişimi kontrol eder. Havuzdaki kaynaklardan biri uygun oluncaya kadar Wait () 'e ve havuza geri verildiğinde Sinyal () ' e kadar işlem sağlar.

Bir Semafor'un koruduğu kaynak sayısı 1'den büyük olduğunda, buna a Sayma Semafor denir. Bir kaynağı kontrol ettiğinde, Boolean Semafor olarak adlandırılır. Bir boole semaforu bir muteks ile eşdeğerdir.

Dolayısıyla bir Semafor Mutex'ten daha yüksek bir soyutlamadır. Bir Mutex, bir Semafor kullanarak uygulanabilir, ancak tam tersi olmaz.

8
Charan

Değiştirilmiş soru şudur - "Linux'ta" bir muteks ile bir "ikili" semafor arasındaki fark nedir?

Cevap: Takip eden farklar - i) Kapsam - Mutex'in kapsamı, onu yaratan ve ipliklerin senkronizasyonu için kullanılan bir işlem adres alanı içindedir. Oysa semafor işlem alanı boyunca kullanılabilir ve dolayısıyla işlemler arası senkronizasyonu için kullanılabilir.

ii) Mutex semafordan daha hafif ve daha hızlıdır. Futex daha da hızlı.

iii) Mutex, aynı sayıda, aynı sayıda serbest bırakması şartıyla, birçok kez başarıyla aynı iş parçacığıyla edinilebilir. Edinmeye çalışan diğer iş parçacığı engeller. Semafor durumunda, aynı işlem tekrar elde etmeye çalışırsa, sadece bir kez alınabileceği için engeller.

6
Mickey

Mutex kritik bölgeleri bloke etmeye çalışıyor, fakat Semafor sayıma göre çalışıyor.

6
Askkan

İkili semafor ve Mutex arasındaki fark: SAHİP OLUŞTURMA: Semaforlar mevcut olmayan bir sahibinden bile gösterilebilir. Sahibi olmasa da, başka herhangi bir konudan kolayca mesaj gönderebilirsiniz.

Semafor sürecinde kamuya açık bir mülktür, Sahip olmayan bir iş parçacığı tarafından kolayca yayınlanabilir. Lütfen bu farkı BOLD harfleriyle işaretleyin, bu çok şey ifade eder.

5
buddingspacer

http://www.geeksforgeeks.org/archives/9102 detaylı olarak tartışır.

Mutex, bir kaynağa erişimi senkronize etmek için kullanılan kilitleme mekanizmasıdır. Semaphore, sinyal mekanizmasıdır.

Muteks yerine ikili semafor kullanmak istiyorsa programlayıcıya kalmıştır.

5
user1852497

Pencerelerde fark aşağıdaki gibidir. MUTEX: başarıyla yürüten işlem wait a signal komutunu çalıştırmak zorundadır. BINARY SEMAPHORES: Farklı işlemler semaforda wait veya signal işlemini gerçekleştirebilir.

4
ajay bidari

Mutekslerin bir sahibi olması dışında, iki nesne farklı kullanım için optimize edilebilir. Muteksler sadece kısa bir süre tutulacak şekilde tasarlanmıştır; Bunun ihlali, düşük performansa ve haksız zamanlamaya neden olabilir. Örneğin, bir başka iş parçacığı üzerinde engellenmiş olsa bile, çalışan bir iş parçacığının bir muteks edinmesine izin verilebilir. Semaforlar daha fazla adalet sağlayabilir veya adalet birkaç koşul değişkeni kullanılarak zorlanabilir.

4
jilles

Konsept yukarıdaki yazılar üzerinden geçtikten sonra bana açıktı. Ancak bazı kalıcı sorular vardı. Bu yüzden bu küçük kod parçasını yazdım.

Almadan bir semafor vermeye çalıştığımızda, geçer. Ancak, almadan bir muteks vermeye çalıştığınızda, başarısız olur. Bunu bir Windows platformunda test ettim. Bir MUTEX kullanarak aynı kodu çalıştırmak için USE_MUTEX'i etkinleştirin.

#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1

DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );

HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;


int main(void)
{

#ifdef USE_MUTEX
    ghMutex = CreateMutex( NULL, FALSE, NULL);
    if (ghMutex  == NULL) 
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }
#else
    // Create a semaphore with initial and max counts of MAX_SEM_COUNT
    ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }
#endif
    // Create thread 1.
    Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);  
    if ( Handle_Of_Thread_1 == NULL)
    {
        printf("Create first thread problem \n");
        return 1;
    }

    /* sleep for 5 seconds **/
    Sleep(5 * 1000);

    /*Create thread 2 */
    Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);  
    if ( Handle_Of_Thread_2 == NULL)
    {
        printf("Create second thread problem \n");
        return 1;
    }

    // Sleep for 20 seconds
    Sleep(20 * 1000);

    printf("Out of the program \n");
    return 0;
}


int my_critical_section_code(HANDLE thread_handle)
{

#ifdef USE_MUTEX
    if(thread_handle == Handle_Of_Thread_1)
    {
        /* get the lock */
        WaitForSingleObject(ghMutex, INFINITE);
        printf("Thread 1 holding the mutex \n");
    }
#else
    /* get the semaphore */
    if(thread_handle == Handle_Of_Thread_1)
    {
        WaitForSingleObject(ghSemaphore, INFINITE);
        printf("Thread 1 holding semaphore \n");
    }
#endif

    if(thread_handle == Handle_Of_Thread_1)
    {
        /* sleep for 10 seconds */
        Sleep(10 * 1000);
#ifdef USE_MUTEX
        printf("Thread 1 about to release mutex \n");
#else
        printf("Thread 1 about to release semaphore \n");
#endif
    }
    else
    {
        /* sleep for 3 secconds */
        Sleep(3 * 1000);
    }

#ifdef USE_MUTEX
    /* release the lock*/
    if(!ReleaseMutex(ghMutex))
    {
        printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
    }
#else
    if (!ReleaseSemaphore(ghSemaphore,1,NULL) )      
    {
        printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
    }
#endif

    return 0;
}

DWORD WINAPI Thread_no_1( LPVOID lpParam ) 
{ 
    my_critical_section_code(Handle_Of_Thread_1);
    return 0;
}


DWORD WINAPI Thread_no_2( LPVOID lpParam ) 
{
    my_critical_section_code(Handle_Of_Thread_2);
    return 0;
}
4
Raghav Navada

Bir ikili semafor bir muteks olarak kullanılabilse de, bir muteks daha spesifik bir kullanım durumudur, çünkü sadece muteksi kilitleyen işlemin kilidini açması beklenir. Bu mülkiyet kısıtlaması, aşağıdakilere karşı koruma sağlamayı mümkün kılar:

  • Kazara serbest bırakma
  • Özyinelemeli kilitlenme
  • Görev Ölüm Kilitlenme

Bu kısıtlamalar her zaman mevcut değildir, çünkü hızı düşürürler. Kodunuzun geliştirilmesi sırasında bu kontrolleri geçici olarak etkinleştirebilirsiniz.

Örneğin. Muteksinizde Hata denetimi özelliğini etkinleştirebilirsiniz. Muteksleri kontrol ederken hata, aynı olanı iki kez kilitlemeye çalışırsanız EDEADLK döndürür ve kendinize ait olmayan bir muteksin kilidini açarsanız EPERM döndürür.

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);

İlk başlatıldığında bu kontrolleri kodumuza şöyle koyabiliriz:

if(pthread_mutex_unlock(&mutex)==EPERM)
 printf("Unlock failed:Mutex not owned by this thread\n");
3
Adi06411

Mutex, hassas kod ve verileri korumak için kullanılır, semafor senkronizasyon için kullanılır. Ayrıca, hassas kodu korumak için pratik olarak da kullanabilirsiniz, ancak işlem sırasında diğer iş parçacığı tarafından korumayı serbest bırakma riski olabilir. bi-semafor ve muteks arasındaki fark mülkiyettir. Örneğin, tuvalete göre, Mutex tuvalete girip kapıyı kilitleyebilir, adam çıkana kadar kimse giremez, bi-semafor girebilir tuvalet ve kapıyı kilitlemek, ancak yöneticiden kapıyı açmasını isteyerek başkası girebilir, bu çok saçma.

2
mannnnerd

dışlama

Mutex'ler genellikle birden fazla iş parçacığı tarafından aynı anda yürütülemeyen bir yeniden giriş kodunun bir bölümüne erişimi seri hale getirmek için kullanılır. Bir mutex nesnesi yalnızca bir iş parçacığının kontrollü bir bölüme girmesine izin verir ve bu iş parçasına erişmeye çalışan diğer iş parçacıklarını ilk iş parçasından çıkana kadar beklemeye zorlar. Bir muteksin kullanımının ortak bir kaynağı korumak tehlikeli olabilir. istenmeyen yan etki. Farklı önceliklerde çalışan ve bir muteks aracılığıyla koordine eden iki RTOS görev, öncelikli inversiyon . Mutex kullanıcı alanında çalışır.

Semaphore

Semafor bir sinyal mekanizmasıdır. Semafor, paylaşılan bir kaynağın eşzamanlı kullanıcılarının sayısını maksimum sayıya kadar sınırlar. Konular kaynağa erişim talep edebilir (semaforu azaltarak) ve kaynağı kullanarak bitirdiklerini (semafor artırarak) işaret edebilir. İş parçacığı sayısının paylaşılan kaynaklara erişmesine izin verir. Bir semaforun doğru kullanımı bir görevden diğerine sinyal vermek içindir. Semaforlar ayrıca bir işaretinden de kullanılabilir. bir hizmete hizmet rutini kesmek (ISR). Semafor sinyali, engelleyici olmayan bir RTOS davranışıdır ve böylece ISR güvenlidir. Çünkü bu teknik hataya yatkın olan ihtiyacı, görev seviyesinde kesintileri devre dışı bırakma ihtiyacını ortadan kaldırır. Bu, çekirdek uzayında .

1
Gopika BG

Mutekselerin semaforların aksine mülkiyeti vardır. Her ne kadar herhangi bir iş parçacığı, bir muteks kapsamında, kilidi açılmış bir muteks alabilir ve aynı kritik kod bölümüne erişebilir, sadece bir muteksi kilitleyen iş parçacığı olmalıdır kilidini aç .

1
laksbv

Mutex ve ikili semafor aynı kullanımdadır, ancak gerçekte farklıdırlar.

Muteks durumunda, yalnızca kilitlemiş olan iplik kilidini açabilir. Başka bir iplik kilitlemeye gelirse, bekleyecektir.

Semafon durumunda, durum böyle değil. Semafor belirli bir iş parçacığı kimliği ile bağlı değildir.

1
Neeraj Sh

Cevap, hedef işletim sistemine bağlı olabilir. Örneğin, aşina olduğum en az bir RTOS uygulaması, hepsi aynı iş parçacığı bağlamında oldukları sürece, tek bir işletim sistemi muteksine karşı çoklu sıralı "alma" işlemlerine izin verecektir. Başka bir iş parçacığının muteks almasına izin verilmeden önce, çoklu alıcının eşit sayıda oyuk ile değiştirilmesi gerekir. Bu, konu bağlamından bağımsız olarak, bir kerede yalnızca tek bir alıma izin verilen ikili semaforlardan farklıdır.

Bu tür bir muteksin ardındaki fikir, bir nesneyi yalnızca tek bir içeriğin bir anda değiştirmesine izin vererek korumanızdır. İş parçacığı muteks alır ve sonra nesneyi daha da değiştiren bir işlev çağırsa bile (ve koruyucu mutex'i kendi işlemlerinin çevresine koyan/koyan), işlemlerin hepsi güvenli olduğundan, hepsi tek bir iş parçacığı altında gerçekleşir.

{
    mutexGet();  // Other threads can no longer get the mutex.

    // Make changes to the protected object.
    // ...

    objectModify();  // Also gets/puts the mutex.  Only allowed from this thread context.

    // Make more changes to the protected object.
    // ...

    mutexPut();  // Finally allows other threads to get the mutex.
}

Elbette, bu özelliği kullanırken, tek bir iş parçacığı içindeki tüm erişimlerin gerçekten güvenli olduğundan emin olmalısınız!

Bu yaklaşımın ne kadar yaygın olduğundan veya tanıdığım sistemlerin dışında uygulanıp uygulanmadığından emin değilim. Bu tür bir muteks örneği için ThreadX RTOS'a bakın.

1
Casey Barker

Buradaki birçok insanın bahsettiği gibi, kritik bir kod parçasını korumak için bir muteks kullanılır (AKA kritik bölüm.) Mutex (kilit), kritik bölüme girer ve mutex (kilit açma) komutlarını aynı iş parçacığında bırakırsınız. .

Bir semafor kullanırken, bir iş parçacığının bir semafor üzerinde beklemesini (A iş parçacığı diyelim), başka bir iş parçacığı (iş parçacığı B diyelim) görevini tamamlayana kadar bekleyebilir ve ardından Semafor'u A iş parçacığının beklemeyi durdurması ve görevine devam etmesi için ayarlar.

1
Dom045

Temel sorun eşzamanlılıktır. Birden fazla kontrol akışı var. Paylaşılan hafızayı kullanarak iki işlemi düşünün. Artık bir seferde yalnızca bir işlem paylaşılan hafızaya erişebilir. Aynı anda birden fazla işlem paylaşılan hafızaya erişirse, paylaşılan hafızanın içeriği bozulur. Demiryolu izi gibi. Sadece bir tren üzerinde koşabilir, aksi takdirde bir kaza olur. Yani bir sürücünün kontrol ettiği bir sinyalizasyon mekanizması var. Sinyal yeşilse, tren gidebilir ve kırmızıysa, izi kullanmak için beklemek zorunda kalır. Benzer şekilde paylaşılan hafıza durumunda, ikili bir semafor vardır. Semafor 1 ise, bir işlem onu ​​alır (0 yapar) ve devam eder ve ona erişir. Semafor 0 ise, işlem bekler. İkili semaforun sağlaması gereken işlevler karşılıklı dışlamadır (ya da kısaca muteks), böylece bir çok eşzamanlı varlıktan sadece biri (işlem ya da iş parçacığı) diğerlerini dışlar. Bir kaynağın birden fazla örneğini senkronize etmeye yardımcı olan sayma semaforlarına sahip olmamız bir artı.

Karşılıklı dışlama, semaforların sağladığı temel işlevdir. Şimdi, iş parçacığı bağlamında, bunun için farklı bir ad ve sözdizimi olabilir. Ancak, temel kavram aynıdır: eşzamanlı programlamada kod ve veri bütünlüğünün nasıl korunacağı. Benim düşünceme göre, mülkiyet ve ilgili kontroller gibi şeyler uygulamalar tarafından sağlanan iyileştirmelerdir.

0
kjohri

"ikili semafor", "mutex" gibi bir "semafor" kullanmak için kullanılan bir programlama dilidir. Görünüşe göre iki büyük fark var:

  1. Her birini arama şekliniz.

  2. "Tanımlayıcı" nın maksimum uzunluğu.

0
ilias iliadis