İkili semafor ve muteks arasında herhangi bir fark var mıdır yoksa esasen aynı mıdır?
İkili semafor ve muteks arasında herhangi bir fark var mıdır yoksa esasen aynı mıdır?
Yanıtlar:
Bunlar DEĞİL aynı şey. Farklı amaçlar için kullanılırlar!
Her iki semafor türü de tam / boş bir duruma sahip olsa ve aynı API'yı kullanıyor olsa da, 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 şu anda Görev A tarafından tutulan bir muteksi semG vermeye çalışırsa, Görev B'nin çağrısı bir hata döndürür ve başarısız olur.
Muteksler her zaman aşağıdaki sırayı kullanır:
- SemTake - Kritik Bölüm - SemGive
İşte basit bir örnek:
Konu A Konu B Mutex'i al verilere eriş ... Mutex'i Al <== Engellenecek ... Mutex'e erişim verisi ver <== Engellemeyi kaldır ... Muteks ver
İkili Semafor
İkili Semafor tamamen farklı bir soruyu ele alır:
Task A Task B
... Take BinSemaphore <== wait for something
Do Something Noteworthy
Give BinSemaphore do something <== unblocks
İkili bir semaforla, B'nin semaforu alması ve A'nın onu vermesi iyi olur.
Yine, bir ikili semafor bir kaynağı erişimden korumaz. Bir semafor verme ve alma eylemi temelde birbirinden ayrılmıştır.
Aynı görevin aynı ikili semaforu vermesi ve alması pek mantıklı değildir.
semaforlar üretici-tüketici gibi bazı senkronizasyon problemleri için daha uygundur.
Windows'ta ikili semaforlar mutekslerden ziyade olay nesnelerine benzer.
Mutex can be released only by thread that had acquired it
- Ben sadece basit bir pthread_mutex tabanlı bir program ile denedim, bir iş parçacığı ana iş parçacığında kilitli muteks kilidini açabilir
Tuvalet örneği keyifli bir benzetmedir:
Karşılıklı dışlama:
Tuvaletin anahtarıdır. Bir kişi o zaman anahtarı alabilir - tuvaleti işgal edebilir. Bittiğinde, kişi kuyruktaki bir sonraki kişiye anahtarı verir (serbest bırakır).
Resmi olarak: "Muteksler tipik olarak, birden fazla iş parçacığı tarafından aynı anda yürütülemeyen yeniden giriş kodunun bir bölümüne erişimi serileştirmek için kullanılır. Mutex nesnesi, yalnızca bir iş parçacığının kontrollü bir bölüme izin vererek erişim sağlamaya çalışan diğer iş parçacıklarını zorlar. bu bölümden ilk iş parçacığının çıkmasını bekleyin. " Ref: Symbian Geliştirici Kütüphanesi
(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 varsayalım. Semafor sayısı - anahtar sayısı - başlangıçta 4 olarak ayarlanır (dört tuvaletin tümü ücretsizdir), o zaman sayım değeri insanlar geldikçe azaltılır. Tüm tuvaletler doluysa, yani. boş anahtar kalmaz, semafor sayısı 0'dır. Şimdi, eq. bir kişi tuvaleti terk eder, semafor 1'e (bir serbest anahtar) yükseltilir ve sıradaki bir sonraki kişiye verilir.
Resmi olarak: "Bir semafor, paylaşılan bir kaynağın eşzamanlı kullanıcı sayısını maksimum sayıya kadar kısıtlar. İş parçacıkları kaynağa erişim talebinde bulunabilir (semaforu azaltarak) ve kaynağı (semaforu arttırarak) bitirdiklerini belirtebilir. " Ref: Symbian Geliştirici Kütüphanesi
Konuyla ilgili güzel makaleler:
2. bölümden:
Muteks, önemli bir fark olan ikili semaforun ilkelerine benzer: sahiplik ilkesi. Sahiplik, bir görev muteksi sadece kilitlediğinde (edindiğinde) yalnızca kilidini açabileceği (serbest bırakabileceği) basit bir kavramdır. Bir görev kilitlenmediği (dolayısıyla sahip olmadığı) bir muteksin kilidini açmaya çalışırsa, bir hata koşuluyla karşılaşılır ve en önemlisi muteksin kilidi açılmaz. Karşılıklı dışlama nesnesinin mülkiyeti yoksa, adı verilenle alakasızsa, bir muteks değildir.
Yukarıdaki cevapların hiçbiri karışıklığı temizlemediğinden, karışıklığımı gideren bir soru.
Kesin olarak, muteks bir kaynağa erişimi senkronize etmek için kullanılan bir kilitleme mekanizmasıdır . Muteksi yalnızca bir görev (işletim sistemi soyutlamasına dayanan bir iş parçacığı veya işlem olabilir) alabilir. Bu, mutex ile ilişkili sahiplik olacağı ve kilidi yalnızca mutex (mutex) serbest bırakabileceği anlamına gelir.
Semafor sinyal mekanizmasıdır (“Ben yaptım, devam edebilirsiniz” sinyali). Örneğin, cep telefonunuzdan şarkı dinliyorsanız (tek bir görev olarak varsayalım) ve aynı zamanda arkadaşınız sizi aradıysa, bir kesme servis rutininin (ISR) çağrı işleme görevini uyandırmaya bildireceği bir kesinti tetiklenir .
Senkronizasyon semantikleri çok farklıdır:
Böyle bir görevlere görev ve trafik gibi Semafora geçirilen bir nişanesi olarak bir muteksi görebileceğiniz gibi kırmızı ışık (o sinyalleri o devam edebileceğinizi birisini).
Teorik düzeyde, anlamsal olarak farklı değildirler. Semaforları kullanarak bir muteksi uygulayabilirsiniz veya bunun tersi de geçerlidir ( örnek için buraya bakın ). 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ı olmasını amaçlamasıdır. Oracle-konuşmasında, muteksler mandallar ve semaforlar bekleme 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, kesilemeyen tek bir komutla yazar . Bu, muteks alıp, önünüzde başka birinin olup olmadığını görmek için test yapabileceğiniz anlamına gelir.
Tipik bir muteks uygulamasında, sınama ve ayarlama talimatını yürüten ve başka bir şeyin muteksi ayarlayıp ayarlamadığını değerlendiren bir işlem veya iş parçacığı vardır. Burada kilit nokta, zamanlayıcı ile etkileşim olmamasıdır , bu yüzden kilidi kimin ayarladığı hakkında hiçbir fikrimiz yoktur (ve umursamıyoruz). Sonra zaman dilimimizden vazgeçeriz ve görev yeniden zamanlandığında tekrar deneriz veya bir döndürme kilidi uygularız . 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 ( kritik bölüm olarak bilinir) yürütmeyi bitirdiğimizde , muteks değerini sıfıra veya 'temiz' anlamına gelen herhangi bir şeye ayarladık. Birden çok görev muteksi elde etmeye çalışıyorsa, muteks serbest bırakıldıktan sonra zamanlanacak bir sonraki görev kaynağa erişecektir. Genellikle muteksleri, normalde paylaşılan bir veri yapısında bir güncelleme yapmak için özel erişimin çok kısa sürelerde gerekli olduğu senkronize edilmiş bir kaynağı kontrol etmek için kullanırsınız.
Bir semafor, bir sayım ve zamanlayıcı ile muteks kütüphanelerinden biraz daha derinlikte etkileşen bazı sistem çağrı sarmalayıcıları olan senkronize bir 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 görevleri engellemek için kullanılır . Bunun basit bir örneği için bkz. Üretici / Tüketici Sorunu . Semaforlar belirli bir değere getirilir - ikili bir semafor, semaforun 1'e başlatıldığı özel bir durumdur. Semafora gönderme işlemi, bekleme sürecini uyandırma etkisine sahiptir.
Temel bir semafor algoritması şuna benzer:
(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 söz konusu olduğunda, ikisi arasındaki temel pratik fark, gerçek veri yapısını çevreleyen sistem hizmetlerinin doğasıdır.
EDIT: evan haklı olarak işaret ettiği gibi, spinlocks tek bir işlemci makinesini yavaşlatacaktır. Tek işlemcide muteksi tutan işlem başka bir görev çalışırken asla sıfırlanmayacağından, yalnızca çok işlemcili bir kutuda bir döndürme kilidi kullanırsınız. Spinlock'lar yalnızca çok işlemcili mimarilerde kullanışlıdır.
futex
sistem çağrısı yardımcı olmak için var olan düşük gecikmeli userspace muteksin / semafor uygulamaları. en.wikipedia.org/wiki/Futex ) kaynak Yakında olursa no-çekişme hızlı yolunda, ya, sen yükü asla bir sistem çağrısı. Ama birkaç mikro saniyeden fazla meşgul beklemeden (eğirme) harcamıyorsunuz. Döngü geri tepme ve bekleme parametrelerini ayarlamak elbette donanıma ve iş yüküne bağlıdır, ancak standart kütüphanenin genellikle makul seçenekleri vardır.
Muteks ve semaforlar senkronizasyon ilkelleri olarak kullanılsa da, aralarında büyük bir fark vardır. Muteks durumunda, yalnızca muteksi kilitleyen veya alan iplik, kilidini açabilir. Bir semafor durumunda, bir semaforda bekleyen bir iplik farklı bir iplik tarafından sinyal verilebilir. Bazı işletim sistemleri süreç arasında muteks ve semafor kullanımını destekler. Genellikle kullanım paylaşılan bellekte oluşturuluyor.
Mutex: Varsayalım ki T1'in erişmek istediği kritik bölüm iş parçacığımız var, o zaman aşağıdaki adımları takip ediyor. T1:
İkili semafor: Sinyal bekleme ve sinyaline göre çalışır. bekleme (ler) değeri "s" değerini bir azaltır "s" değeri "1" değeri ile başlar, sinyal (ler) "s" değerini bir arttırır. "s" değeri 1 ise, hiç kimse kritik bölüm kullanmadığı anlamına gelir, değer 0 ise kritik bölüm kullanımda demektir. T2 ipliğinin kritik bölüm kullandığını varsayalım, aşağıdaki adımları takip eder. T2:
İş parçacığı kritik bölümü kilitlerse Mutex ve İkili semafor arasındaki temel fark, kritik bölümün kilidini açması gerekiyorsa, başka bir iş parçacığının kilidini açamaz, ancak bir iş parçacığı bekleme (ler) işlevini kullanarak kritik bölümü kilitlerse, İkili semafor durumunda değer "s" değeri "0" olur ve hiç kimse "s" değeri 1 oluncaya kadar erişemez, ancak diğer bazı iş parçacığı çağrı sinyal (ler) inin ardından "s" değerinin 1 olduğunu ve diğer işlevin kritik bölüm kullanmasına izin verdiğini varsayalım. dolayısıyla İkili semafor iş parçacığında sahiplik yoktur.
Windows'ta muteksler ve ikili semaforlar arasında iki fark vardır:
Bir muteks yalnızca sahipliği olan bir iş parçacığı, yani daha önce Bekleme işlevini çağıran (veya oluştururken sahiplik alan iş parçacığı) tarafından serbest bırakılabilir. Bir semafor herhangi bir iplik tarafından serbest bırakılabilir.
Bir iş parçacığı, bir muteks üzerinde engellemeden art arda bekleme işlevini çağırabilir. Ancak, aradaki semaforu serbest bırakmadan ikili bir semaforda iki kez bekleme işlevini çağırırsanız, iş parçacığı engellenir.
Mutex'i, bir iş parçacığındaki bir veriyi aynı anda başka bir iş parçacığına erişirken kilitlemek için kullanırsınız. Az önce aradığınız lock()
ve verilere erişme sürecinde olduğunuzu varsayın . 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 beklemediğiniz anlamına gelir. Diğer bir deyişle, farklı bir iş parçacığı örneğinde yürütülen aynı iş parçacığı kodu ise, kilide çarparsalock()
orada kontrol akışını engellemelidir. Bu, aynı verilere erişen ve aynı muteks tarafından da kilitlenen farklı bir iş parçacığı kodu kullanan bir iş parçacığı için geçerlidir. Bu durumda, hala verilere erişme sürecindesiniz ve diyelim ki muteks kilidine ulaşmak için 15 saniye daha sürebilir (böylece muteks kilidinde engellenen diğer iş parçacığının engellenmesi ve denetimin verilere erişim). Herhangi bir maliyetle, başka bir iş parçacığının aynı muteksin kilidini açmasına izin veriyor musunuz ve sırayla, muteks kilidinde zaten bekleyen iş parçacığının engelini kaldırmasına ve verilere erişmesine izin veriyor musunuz? Umarım burada söylediğimi elde edersin? Göre, evrensel tanım üzerinde anlaştı !,
Bu nedenle, muteks yerine ikili semafor kullanma konusunda çok titizseniz, kilitleri "açmak" için çok dikkatli olmalısınız. Demek istediğim, her kilide çarpan her kontrol akışı bir kilit açma çağrısına çarpmalı, ayrıca herhangi bir “ilk kilit açma” olmamalı, her zaman “ilk kilit” olmalıdır.
Mutex "Kilit Mekanizmaları" için kullanılır. tek seferde bir işlem paylaşılan bir kaynağı kullanabilir
buna karşılık
Semaforlar, "Sinyalleme Mekanizmaları" için "Bitti, şimdi devam edebilir" gibi
Efsane:
Makalenin bir çiftinde "ikili semafor ve muteks aynıdır" veya "1 değerine sahip semafor mutekstir", ancak temel fark Mutex'in yalnızca edinmiş olan iş parçacığı tarafından serbest bırakılabilirken, diğer herhangi bir iş parçacığından semafor sinyalini verebilirsiniz
Anahtar noktaları:
• Bir iş parçacığı birden fazla kilit alabilir (Mutex).
• Muteks, tekrarlayan bir muteks olması durumunda birden fazla kez kilitlenebilir, burada muteks için kilitleme ve kilit açma aynı olmalıdır
• Eğer zaten bir muteksi kilitlemiş bir evre, muteksi tekrar kilitlemeye çalışırsa, o muteksin bekleme listesine girerek çıkmaza neden olur.
• İkili semafor ve muteks benzerdir ancak aynı değildir.
• Mutex, kendisiyle ilişkili koruma protokolleri nedeniyle maliyetli bir işlemdir.
• Muteksin ana amacı, atomik erişim veya kaynak kilidi sağlamaktır
Bir dışlama tek paylaşılan bir kaynağa erişimi kontrol eder. Söz konusu kaynağa erişim elde etmek () ve bittiğinde onu yayınlamak () için işlemler sağlar.
Bir Semafor , paylaşılan bir kaynak havuzuna erişimi denetler. Bu kadar işlemler sağlar bekleyin () havuz kullanılabilir hale içinde kaynaklardan biri kadar ve Sinyal () geri havuzuna verildiğinde.
Bir Semaforun koruduğu kaynak sayısı 1'den fazla olduğunda buna Sayma Semaforu denir . Bir kaynağı kontrol ettiğinde, buna Boole Semaforu denir . Boole semaforu bir mutekse eşdeğerdir.
Dolayısıyla, bir Semafor Mutex'ten daha yüksek bir soyutlamadır. Bir Mutex bir Semafor kullanılarak uygulanabilir ancak tam tersi şekilde kullanılamaz.
Değiştirilmiş soru - "Linux" da bir muteks ile "ikili" semafor arasındaki fark nedir?
Cvp: Aşağıdaki farklar şunlardır - i) Kapsam - Muteksin kapsamı, onu oluşturan ve iş parçacıklarının senkronizasyonu için kullanılan bir işlem adres alanı içindedir. Oysa semafor proses alanı boyunca kullanılabilir ve bu nedenle süreçler arası senkronizasyon için kullanılabilir.
ii) Mutex hafiftir ve semafordan daha hızlıdır. Futex daha da hızlı.
iii) Mutex, aynı iş parçacığı tarafından aynı sayıda bırakılması şartıyla birçok kez başarılı bir şekilde edinilebilir. Almaya çalışan diğer iş parçacığı engeller. Semafor durumunda aynı işlem tekrar elde etmeye çalışırsa, sadece bir kez alınabileceğinden engeller.
İkili Semafor ve Muteks arasındaki fark: MÜLKİYET: Semaforlar, mevcut olmayan bir sahibinden bile sinyal verilebilir (kaydedilebilir). Bu, sahibi olmasanız bile, başka bir iş parçasından yayın gönderebileceğiniz anlamına gelir.
Semafor kamuya açık bir süreçtir, basitçe sahibi olmayan bir iş parçacığı tarafından gönderilebilir. Lütfen bu farkı Kalın harflerle işaretleyin, bu çok fazla anlam ifade ediyor.
Muteks kritik bölgeyi engellemeye çalışıyor, ama Semaphore sayılıyor.
http://www.geeksforgeeks.org/archives/9102 ayrıntılı 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 programcıya kalmıştır.
Mutekslerin bir sahibi olması dışında, iki nesne farklı kullanım için optimize edilebilir. Muteksler sadece kısa bir süreliğine tutulacak şekilde tasarlanmıştır; bunu ihlal etmek performansın düşmesine ve haksız programlamaya neden olabilir. Örneğin, başka bir iş parçacığı zaten engellenmiş olsa bile, çalışan bir iş parçacığının muteks almasına izin verilebilir. Semaforlar daha fazla adalet sağlayabilir veya adalet birkaç koşul değişkeni kullanılarak zorlanabilir.
sem_post()
için SCHED_FIFO
ve SCHED_RR
(bunlardan ikisi varsayılan değildir): En yüksek öncelikli konu ve aynı önceliğe, en uzun beklediği iplikle birden varsa. OpenSolaris bu FIFO kuralını normal programlama için bile bir dereceye kadar takip eder. Glibc ve FreeBSD için, basit bir muteksin kilidini açmak (yani öncelikli koruma veya öncelik devralma değil) ve bir semafor yayınlamak temelde aynıdır, nesneyi kilitsiz olarak işaretler ve ardından bekleyen iş parçacıkları varsa, çekirdeği uyandırmak için çağırır.
Pencerelerde fark aşağıdaki gibidir. Karşılıklı dışlama: başarılı bir şekilde çalıştırır işlem beklemek bir çalıştırmak için olan bir sinyal ve tersi. İKİLİ ŞEMALAR: Farklı işlemler semaforda bekleme veya sinyal işlemi gerçekleştirebilir.
İkili bir semafor bir muteks olarak kullanılabilirken, muteks daha spesifik bir kullanım-durumudur, çünkü sadece muteksi kilitleyen işlemin kilidini açması gerekir. Bu sahiplik kısıtlaması aşağıdakilere karşı koruma sağlamayı mümkün kılar:
Bu kısıtlamalar her zaman mevcut değildir, çünkü hızı düşürürler. Kodunuzun geliştirilmesi sırasında bu denetimleri geçici olarak etkinleştirebilirsiniz.
örneğin, muteksinizde Hata denetimi özelliğini etkinleştirebilirsiniz. EDEADLK
Aynı şeyi iki kez kilitlemeye çalışırsanız ve EPERM
size ait olmayan bir muteksin kilidini açarsanız muteksleri döndürme hatası .
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);
Başlatıldıktan sonra bu kontrolleri kodumuza şu şekilde yerleştirebiliriz:
if(pthread_mutex_unlock(&mutex)==EPERM)
printf("Unlock failed:Mutex not owned by this thread\n");
Yukarıdaki mesajların üzerinden geçtikten sonra kavram benim için açıktı. Ama devam eden bazı sorular vardı. Bu küçük kod parçasını yazdım.
Almadan bir semafor vermeye çalıştığımızda geçer. Ancak, muteksi almadan almadan 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şlevini 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;
}
Semaforun "bir kaynak kullanılarak yapıldığı" sinyalini vermesi gerçeği, kaynağa hiç sahip olmamış olsa bile, semaforlar durumunda sahiplenme ve sinyalleşme arasında çok gevşek bir bağlantı olduğunu düşündürüyor.
Mutex hassas kodu ve verileri korumak için kullanılır, semafor senkronizasyon için kullanılır.Ayrıca hassas kodu korumak için pratik kullanıma sahip olabilirsiniz, ancak V. V. ana işlemle korumayı diğer iş parçacığı tarafından serbest bırakma riski olabilir. iki semafor ve muteks arasındaki fark mülkiyettir.Örneğin tuvalet ile, Mutex tuvalete girip kapıyı kilitleyebilir, kimse çıkana kadar kimse giremez, bi-semafor girebilir tuvalet ve kapıyı kilitlemek, ama başka biri yöneticiden kapıyı açmasını isteyerek girebilir, bu çok saçma.
Karşılıklı dışlama
Muteksler tipik olarak, birden fazla iş parçacığıyla aynı anda yürütülemeyen yeniden giriş kodunun bir bölümüne erişimi serileştirmek için kullanılır. Mutex nesnesi, yalnızca bir iş parçacığının kontrollü bir bölüme izin verir ve bu bölüme erişim elde etmeye çalışan diğer iş parçacıklarını ilk iş parçacığından o bölümden çıkana kadar beklemeye zorlar. Muteksin doğru kullanımı, paylaşılan bir kaynağı korumak tehlikeli olabilir istenmeyen yan etki. Farklı önceliklerde çalışan ve bir muteks yoluyla koordine edilen iki RTOS görevi, öncelikli ters çevirme fırsatı yaratır . Mutex kullanıcı alanında çalışır .
Semafor
Semafor bir sinyal mekanizmasıdır. Semafor, paylaşılan bir kaynağın eşzamanlı kullanıcı sayısını maksimum sayıya kadar kısıtlar. İş parçacıkları kaynağa erişim talebinde bulunabilir (semaforu azaltarak) ve kaynağı kullanarak (semaforu arttırarak) bittiğini gösterebilir. Bir semaforun doğru kullanımı, bir görevden diğerine sinyal gönderilmesi içindir. Memaforlar, bir kesme servis yordamından (ISR) bir göreve sinyal vermek için de kullanılabilir . Bir semaforu işaret etmek, engellenmeyen bir RTOS davranışıdır ve dolayısıyla ISR güvenlidir. Bu teknik, görev düzeyinde kesintileri devre dışı bırakma ihtiyacını ortadan kaldırdığı için çekirdek alanında çalışır .
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 olduğu sürece, tek bir OS muteksine karşı birden fazla ardışık "alma" işlemine izin verecektir. Muteksi elde etmek için başka bir iş parçacığının kullanılmasına izin verilmeden önce, çoklu almaların eşit sayıda itme ile değiştirilmesi gerekir. Bu, iplik bağlamından bağımsız olarak, bir seferde yalnızca tek bir alma işlemine izin verilen ikili semaforlardan farklıdır.
Bu tür muteksin arkasındaki fikir, bir nesneyi aynı anda yalnızca tek bir bağlamın değiştirmesine izin vererek korumanızdır. İş parçacığı muteksi alır ve sonra nesneyi daha fazla değiştiren bir işlev çağırsa (ve koruyucu muteksi kendi işlemlerinin etrafına alıp koyarsa), işlemler yine de tek bir iş parçacığı altında gerçekleştiği için güvenli olmalıdır.
{
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.
}
Tabii ki, bu özelliği kullanırken, tek bir iş parçacığındaki 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 ya da tanıdığım sistemler dışında uygulanıp uygulanmadığından emin değilim. Bu tür bir muteks örneği için, bkz. ThreadX RTOS.
Mutekslerin semaforların aksine mülkiyeti vardır. Herhangi bir iş parçacığı olsa da, bir muteksin kapsamında, kod, aynı kritik bölümüne bir kilidi mutex ve kilit erişim elde edebilirsiniz bir muteksi kilitli sadece iplik gerektiğini kilidini .
Burada birçok kişinin belirttiği gibi, kritik bir kod parçasını korumak için bir muteks kullanılır (AKA kritik bölümü.) Muteksi (kilit) alır, kritik bölüme girer ve muteksi (kilidini) aynı iş parçacığında serbest bırakırsınız .
Bir semafor kullanırken, başka bir iş parçacığı (B iş parçacığı diyelim) herhangi bir görevi tamamlayana kadar bir semaforda (A iş parçacığı diyelim) bir iş parçacığı bekletebilir ve daha sonra A'nın işlenmesini durdurmak ve görevine devam etmek için Semaforu A'ya ayarlayabilirsiniz.
En İyi Çözüm
Tek fark
1.Muteks -> kilitleme ve kilidini açma muteksi kilitleyen bir iş parçacığının mülkiyetindedir.
2.Semaphore -> Mülkiyet yok yani; bir iş parçacığı semwait (ler) i çağırırsa, diğer herhangi bir iş parçacığı kilidi kaldırmak için sempost (lar) ı çağırabilir.
Karşılıklı dışlama
Yakın zamana kadar, çekirdekteki tek uyku kilidi semafordu. Semaforların çoğu, bir sayıyla bir semafor başlattı ve bunları karşılıklı hariç tutma kilidi olarak gördü - spin kilidinin uyku versiyonu. Ne yazık ki, semaforlar oldukça geneldir ve herhangi bir kullanım kısıtlaması getirmez. Bu, çekirdek ve kullanıcı alanı arasındaki karmaşık danslar gibi belirsiz durumlarda münhasır erişimi yönetmek için onları kullanışlı kılar. Ancak aynı zamanda daha basit kilitlemenin yapılması daha zor olduğu anlamına gelir ve zorlanan kuralların olmaması her türlü otomatik hata ayıklama veya kısıtlama zorunluluğunu imkansız hale getirir. Daha basit bir uyku kilidi arayan çekirdek geliştiricileri muteksi tanıttı.Yes, şimdi alıştığınız gibi kafa karıştırıcı bir isim. "Muteks" terimi, karşılıklı dışlamayı zorlayan herhangi bir uyku kilidine atıfta bulunan genel bir addır, kullanım sayısı bir olan semafor gibi. Son Linux çekirdeğinde, “mutex” adı, artık karşılıklı dışlamayı uygulayan belirli bir uyku kilidi türüdür.
Muteksin sadeliği ve verimliliği, kullanıcılarına semaforun gerektirdiğinden daha fazla getirdiği ek kısıtlamalardan gelir. Dijkstra'nın orijinal tasarımına uygun olarak en temel davranışı uygulayan bir semafordan farklı olarak, muteksin daha katı ve daha dar bir kullanım durumu vardır: ■ Muteksi aynı anda yalnızca bir görev tutabilir. Yani, muteks üzerindeki kullanım sayısı her zaman birdir.
[1] Linux Çekirdek Geliştirme, Üçüncü Baskı Robert Love
Bence buradaki cevapların çoğu, özellikle muteksin sadece onu tutan süreç tarafından serbest bırakılabileceğini, ancak semaforun bir süreç tarafından sinyal verilebileceğini söyleyenlerin kafa karıştırıcı olduğunu düşünüyorum. Yukarıdaki çizgi semafor açısından biraz belirsizdir. Anlamak için, biri semafor sayma diğeri ise ikili semafor olmak üzere iki çeşit semafor olduğunu bilmeliyiz. Semafor işlemlerinde n kullanımdan önce tanımlanabilen n kaynak sayısına erişir. Her semafor kullanımda olan kaynakların sayısını tutan bir başlangıç değişkenine sahiptir, başlangıçta n olarak ayarlanır. Bir kaynak kullanmak isteyen her işlem, semaforda bir wait () işlemi gerçekleştirir (böylece sayıyı azaltır). Bir işlem bir kaynağı serbest bıraktığında, bir release () işlemi gerçekleştirir (sayımı artırır). Sayı 0 olduğunda, tüm kaynaklar kullanılıyor. Bundan sonra, süreç sayım 0'dan daha fazla olana kadar bekler. Şimdi burada sadece kaynağı tutan işlem sayımı artırabilir, başka hiçbir işlem sayımı artıramaz, sadece bir kaynağı tutan işlemler sayımı ve süreci artırabilir semaforu tekrar kontrol eder ve mevcut kaynağı gördüğünde sayımı tekrar azaltır. Bu nedenle, ikili semafor açısından, yalnızca semaforu tutan işlem sayımı artırabilir ve sayım semaforu kullanmayı bırakıp sayıyı artırana kadar sıfır kalır ve diğer işlem semafora erişim şansı elde eder. Şimdi burada sadece kaynağı tutan işlem sayısını artırabilir başka hiçbir işlem sayımı artıramaz sadece bir kaynağı tutan süreçler sayısını artırabilir ve semafor için bekleyen süreç tekrar kontrol eder ve kullanılabilir kaynak gördüğünde sayımı tekrar azaltır. Bu nedenle, ikili semafor açısından, yalnızca semaforu tutan işlem sayımı artırabilir ve sayım semaforu kullanmayı bırakıp sayıyı artırana kadar sıfır kalır ve diğer işlem semafora erişim şansı elde eder. Şimdi burada sadece kaynağı tutan işlem sayısını artırabilir başka hiçbir işlem sayımı artıramaz sadece bir kaynağı tutan süreçler sayısını artırabilir ve semafor için bekleyen süreç tekrar kontrol eder ve kullanılabilir kaynak gördüğünde sayımı tekrar azaltır. Bu nedenle, ikili semafor açısından, yalnızca semaforu tutan işlem sayımı artırabilir ve sayım semaforu kullanmayı bırakıp sayıyı artırana kadar sıfır kalır ve diğer işlem semafora erişim şansı elde eder.
İkili semafor ve muteks arasındaki temel fark, semaforun bir sinyal mekanizması ve muteksin bir kilitleme mekanizması olmasıdır, ancak ikili semafor karışıklık yaratan muteks gibi işlev görür, ancak her ikisi de farklı işler için uygun farklı kavramlardır.