एक सेमाफोर एक प्रोग्रामिंग अवधारणा है जिसे अक्सर बहु-थ्रेडिंग समस्याओं को हल करने के लिए उपयोग किया जाता है। समुदाय के लिए मेरा प्रश्न:
एक सेमाफोर क्या है और आप इसका उपयोग कैसे करते हैं?
एक सेमाफोर एक प्रोग्रामिंग अवधारणा है जिसे अक्सर बहु-थ्रेडिंग समस्याओं को हल करने के लिए उपयोग किया जाता है। समुदाय के लिए मेरा प्रश्न:
एक सेमाफोर क्या है और आप इसका उपयोग कैसे करते हैं?
जवाबों:
एक नाइट क्लब में बाउंसर के रूप में सेमाफोरस के बारे में सोचो। एक बार में क्लब में अनुमति देने वाले लोगों की एक समर्पित संख्या होती है। यदि क्लब भरा हुआ है तो किसी को भी प्रवेश करने की अनुमति नहीं है, लेकिन जैसे ही एक व्यक्ति दूसरे व्यक्ति को छोड़ता है, वह प्रवेश कर सकता है।
यह एक विशिष्ट संसाधन के लिए उपभोक्ताओं की संख्या को सीमित करने का एक तरीका है। उदाहरण के लिए, किसी एप्लिकेशन में डेटाबेस में एक साथ कॉल की संख्या को सीमित करने के लिए।
यहाँ C # :-) में एक बहुत बड़ा उदाहरण है
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TheNightclub
{
public class Program
{
public static Semaphore Bouncer { get; set; }
public static void Main(string[] args)
{
// Create the semaphore with 3 slots, where 3 are available.
Bouncer = new Semaphore(3, 3);
// Open the nightclub.
OpenNightclub();
}
public static void OpenNightclub()
{
for (int i = 1; i <= 50; i++)
{
// Let each guest enter on an own thread.
Thread thread = new Thread(new ParameterizedThreadStart(Guest));
thread.Start(i);
}
}
public static void Guest(object args)
{
// Wait to enter the nightclub (a semaphore to be released).
Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
Bouncer.WaitOne();
// Do some dancing.
Console.WriteLine("Guest {0} is doing some dancing.", args);
Thread.Sleep(500);
// Let one guest out (release one semaphore).
Console.WriteLine("Guest {0} is leaving the nightclub.", args);
Bouncer.Release(1);
}
}
}
लेख Mutexes और Semaphores Demystified माइकल बर्र से क्या mutexes और सेमाफोर अलग बनाता है में एक महान संक्षिप्त परिचय है, और जब उन्हें करना चाहिए और नहीं किया जाना चाहिए। मैंने कई प्रमुख पैराग्राफ यहाँ प्रस्तुत किए हैं।
मुख्य बिंदु यह है कि साझा संसाधनों की सुरक्षा के लिए म्यूटेक्स का उपयोग किया जाना चाहिए, जबकि सिग्नलिंग के लिए सेमीफोर का उपयोग किया जाना चाहिए। आपको आम तौर पर साझा संसाधनों की रक्षा के लिए सेमाफोर का उपयोग नहीं करना चाहिए, न ही सिग्नलिंग के लिए म्यूटेक्स। उदाहरण के लिए, उदाहरण के लिए, साझा संसाधनों की सुरक्षा के लिए सेमाफोर का उपयोग करने के मामले में बाउंसर सादृश्य के साथ - आप उन्हें उस तरह से उपयोग कर सकते हैं, लेकिन इससे बग का निदान करने में कठिनाई हो सकती है।
जबकि म्यूटेक्स और सेमाफोरस के कार्यान्वयन में कुछ समानताएं हैं, उन्हें हमेशा अलग तरीके से उपयोग किया जाना चाहिए।
शीर्ष पर रखे गए प्रश्न का सबसे आम (लेकिन फिर भी गलत) उत्तर है कि म्यूटेक्स और सेमाफोर बहुत समान हैं, एकमात्र महत्वपूर्ण अंतर यह है कि सेमाफोर एक से अधिक गिनती कर सकते हैं। लगभग सभी इंजीनियर ठीक से समझते हैं कि एक म्यूटेक्स एक द्विआधारी ध्वज है जिसका उपयोग कोड के महत्वपूर्ण खंडों के अंदर आपसी बहिष्कार सुनिश्चित करके एक साझा संसाधन की रक्षा के लिए किया जाता है। लेकिन जब उनसे पूछा गया कि "गिनती के सेमाफोर" का उपयोग करने के तरीके का विस्तार किया जाए, तो अधिकांश इंजीनियर-केवल अपने आत्मविश्वास की डिग्री में भिन्न होते हैं - पाठ्यपुस्तक की राय का कुछ स्वाद व्यक्त करते हैं कि इनका उपयोग कई समान संसाधनों की सुरक्षा के लिए किया जाता है।
...
इस बिंदु पर साझा संसाधनों की रक्षा के रूप में बाथरूम की चाबियाँ के विचार का उपयोग करके एक दिलचस्प सादृश्य बनाया गया है - बाथरूम। यदि किसी दुकान में एक ही बाथरूम है, तो उस संसाधन की सुरक्षा के लिए एक एकल कुंजी पर्याप्त होगी और कई लोगों को एक साथ उपयोग करने से रोक सकती है।
यदि कई बाथरूम हैं, तो किसी को उन्हें समान रूप से कुंजी देने के लिए और कई चाबियाँ बनाने के लिए लुभाया जा सकता है - यह एक सेमाफोर के गलत उपयोग के समान है। एक बार जब आपके पास एक चाबी होती है तो आपको वास्तव में पता नहीं होता है कि कौन सा बाथरूम उपलब्ध है, और यदि आप इस रास्ते से नीचे जाते हैं, तो संभवत: आप उस जानकारी को प्रदान करने के लिए म्यूटेक्स का उपयोग करने जा रहे हैं और सुनिश्चित करें कि आप पहले से कब्जे वाले बाथरूम को न लें। ।
एक सेमाफोर अनिवार्य रूप से एक ही संसाधन के कई की रक्षा करने के लिए गलत उपकरण है, लेकिन यह है कि कितने लोग इसके बारे में सोचते हैं और इसका उपयोग करते हैं। बाउंसर सादृश्य अलग है - एक ही प्रकार के कई संसाधन नहीं हैं, इसके बजाय एक संसाधन है जो एक साथ कई उपयोगकर्ताओं को स्वीकार कर सकता है। मुझे लगता है कि इस तरह की स्थितियों में एक सेमाफोर का उपयोग किया जा सकता है, लेकिन शायद ही कभी वास्तविक दुनिया की परिस्थितियां होती हैं जहां सादृश्य वास्तव में होता है - यह अधिक बार होता है कि एक ही प्रकार के कई होते हैं, लेकिन अभी भी व्यक्तिगत संसाधन, जैसे कि बाथरूम, जिनका उपयोग नहीं किया जा सकता है इस तरफ।
...
एक कार्य से दूसरे कार्य के लिए संकेत के लिए सेमाफोर का सही उपयोग होता है। एक म्यूटेक्स को लेने और जारी करने का मतलब है, हमेशा उस क्रम में, प्रत्येक कार्य द्वारा जो साझा किए गए संसाधन का उपयोग करता है। इसके विपरीत, ऐसे कार्य जो सीमैफ़ोर्स का उपयोग करते हैं, या तो संकेत देते हैं या प्रतीक्षा करते हैं - दोनों नहीं। उदाहरण के लिए, टास्क 1 में कोड (जैसे, सिग्नल या इन्क्रीमेंट) एक विशेष सेमाफोर पोस्ट किया जा सकता है जब "पावर" बटन दबाया जाता है और टास्क 2, जो डिस्प्ले को जगाता है, उसी सेमाफोर पर जाता है। इस परिदृश्य में, एक कार्य ईवेंट सिग्नल का निर्माता है; अन्य उपभोक्ता।
...
यहाँ एक महत्वपूर्ण बिंदु यह है कि म्यूटेक्स रीयल टाइम ऑपरेटिंग सिस्टम के साथ एक बुरे तरीके से हस्तक्षेप करता है, जिससे प्राथमिकता उलटा होती है जहाँ संसाधन साझा करने के कारण कम महत्वपूर्ण कार्य को अधिक महत्वपूर्ण कार्य से पहले निष्पादित किया जा सकता है। संक्षेप में, यह तब होता है जब एक कम प्राथमिकता वाला कार्य एक संसाधन को हथियाने के लिए म्यूटेक्स का उपयोग करता है, फिर बी को हथियाने की कोशिश करता है, लेकिन रोक दिया जाता है क्योंकि बी अनुपलब्ध है। जब यह प्रतीक्षा कर रहा है, एक उच्च प्राथमिकता वाला कार्य साथ आता है और ए की आवश्यकता होती है, लेकिन यह पहले से ही बंधा हुआ है, और एक प्रक्रिया द्वारा जो कि चल भी नहीं रहा है क्योंकि यह बी की प्रतीक्षा कर रहा है। इसे हल करने के कई तरीके हैं, लेकिन यह अक्सर तय हो जाता है म्यूटेक्स और टास्क मैनेजर को बदलकर। म्यूटेक्स बाइनरी सेमाफोर की तुलना में इन मामलों में बहुत अधिक जटिल है,
...
म्यूटेक्स और सेमाफोरस के बीच व्यापक आधुनिक भ्रम का कारण ऐतिहासिक है, क्योंकि यह 1974 में जिम्कास्ट्रा द्वारा सेमफोर (राजधानी "एस", इस लेख में) के आविष्कार के लिए सभी तरह से तारीखें देता है। उस तिथि से पहले, कंप्यूटर वैज्ञानिकों के लिए ज्ञात कोई भी व्यवधान-सुरक्षित कार्य सिंक्रनाइज़ेशन और सिग्नलिंग तंत्र कुशलता से दो से अधिक कार्यों के लिए उपयोग करने योग्य नहीं था। डायजेस्ट्रा के क्रांतिकारी, सुरक्षित और स्केलेबल सेमाफोर को महत्वपूर्ण खंड संरक्षण और सिग्नलिंग दोनों में लागू किया गया था। और इस तरह भ्रम शुरू हुआ।
हालांकि, बाद में प्राथमिकता-आधारित प्रीमेप्टिव आरटीओएस (जैसे, वीआरटीएक्स, सीए 1980) की उपस्थिति के बाद ऑपरेटिंग सिस्टम डेवलपर्स के लिए यह स्पष्ट हो गया, आरएमए की स्थापना करने वाले शैक्षणिक पत्रों का प्रकाशन और प्राथमिकता उलटा के कारण होने वाली समस्याएं, और प्राथमिकता में एक पेपर। 1990 में इनहेरिटेंस प्रोटोकॉल, 3 यह स्पष्ट हो गया कि म्यूटेक्स बाइनरी काउंटर के साथ सिर्फ सेमाफोर से अधिक होना चाहिए।
म्यूटेक्स: संसाधन साझाकरण
सेमाफोर: सिग्नलिंग
साइड इफेक्ट के सावधान विचार के बिना एक दूसरे के लिए उपयोग न करें।
म्यूटेक्स: किसी संसाधन के लिए अनन्य सदस्य का उपयोग
सेमीफोर: एक संसाधन के लिए एन-सदस्य का उपयोग
यही है, एक म्यूटेक्स का उपयोग काउंटर, फ़ाइल, डेटाबेस, आदि तक पहुंच को सिंक्रनाइज़ करने के लिए किया जा सकता है।
एक सेम्पहोर एक ही काम कर सकता है लेकिन एक साथ कॉल करने वालों की निश्चित संख्या का समर्थन करता है। उदाहरण के लिए, मैं अपने डेटाबेस कॉल्स को एक सेमाफोर (3) में लपेट सकता हूं ताकि मेरा मल्टीथ्रेडेड ऐप डेटाबेस को सबसे अधिक 3 एक साथ कनेक्शन से टकराए। तीन स्लॉट में से एक खुलने तक सभी प्रयास अवरुद्ध हो जाएंगे। वे बहुत अच्छी तरह से वास्तव में आसान अनुभवहीन भोली करने जैसी चीजें बनाते हैं।
विचार करें, एक टैक्सी जिसमें चालक सहित कुल 3 ( पीछे ) +2 ( सामने ) व्यक्ति शामिल हो सकते हैं। तो, semaphore
एक समय में कार के अंदर केवल 5 व्यक्तियों को अनुमति देता है। और mutex
कार की एक सीट पर केवल 1 व्यक्ति को अनुमति देता है।
इसलिए, Mutex
विशेष (एक संसाधन के लिए उपयोग की अनुमति है एक OS धागे की तरह , जबकि एक)Semaphore
एक समय में संसाधनों की एन संख्या के लिए अनुमति देना है।
@Craig:
एक सेमाफोर एक संसाधन को लॉक करने का एक तरीका है ताकि यह गारंटी दी जाए कि कोड का एक टुकड़ा निष्पादित किया जाता है, केवल उस कोड के टुकड़े तक उस संसाधन तक पहुंच होती है। यह एक संसाधन को समवर्ती रूप से दो थ्रेड रखता है, जिससे समस्याएं हो सकती हैं।
यह केवल एक धागे तक सीमित नहीं है। किसी संसाधन तक पहुँचने के लिए थ्रेड की निश्चित संख्या की अनुमति देने के लिए एक सेमाफ़ोर कॉन्फ़िगर किया जा सकता है।
सेमाफोर को भी ... सेमाफोर के रूप में इस्तेमाल किया जा सकता है। उदाहरण के लिए यदि आपके पास एक कतार में डेटा की एक से अधिक प्रक्रिया है, और कतार से डेटा लेने वाला केवल एक कार्य है। यदि आप अपने उपभोग कार्य को उपलब्ध डेटा के लिए लगातार कतार में नहीं रखना चाहते हैं, तो आप सेमीफ़ायर का उपयोग कर सकते हैं।
यहाँ सेमाफोर का उपयोग अपवर्जन तंत्र के रूप में नहीं किया जाता है, बल्कि एक संकेतन तंत्र के रूप में किया जाता है। उपभोग कार्य अर्धमात्रा पर प्रतीक्षा कर रहा है। उत्पादक कार्य अर्धमात्रा पर पोस्ट कर रहे हैं।
इस तरह से उपभोग कार्य चल रहा है जब और केवल जब डेटा को समाप्त किया जाना है
समवर्ती कार्यक्रमों के निर्माण के लिए दो आवश्यक अवधारणाएं हैं - तुल्यकालन और पारस्परिक बहिष्करण। हम देखेंगे कि इन दो प्रकार के ताले (सेमाफोर अधिक आम तौर पर एक प्रकार के लॉकिंग तंत्र हैं) हमें सिंक्रनाइज़ेशन और पारस्परिक समावेशन प्राप्त करने में मदद करते हैं।
एक सेमाफोर एक प्रोग्रामिंग कंस्ट्रक्शन है जो हमें सिंक्रोनाइजेशन और म्यूचुअल एक्सक्लूजन दोनों को लागू करके कंसीडर को प्राप्त करने में मदद करता है। सेमाफोर दो प्रकार के होते हैं, बाइनरी और काउंटिंग।
एक सेमाफोर के दो भाग होते हैं: एक काउंटर, और एक विशेष संसाधन तक पहुंचने के लिए प्रतीक्षा करने वाले कार्यों की एक सूची। एक सेमाफोर दो ऑपरेशन करता है: प्रतीक्षा (पी) [यह एक लॉक प्राप्त करने जैसा है], और रिलीज़ (वी) [लॉक जारी करने के समान] - ये केवल दो ऑपरेशन हैं जो एक सेमीफोर पर प्रदर्शन कर सकते हैं। एक बाइनरी सेमाफोर में, काउंटर तार्किक रूप से 0 और 1 के बीच जाता है। आप इसे दो मूल्यों के साथ लॉक के समान होने के बारे में सोच सकते हैं: खुला / बंद। एक गिनती के सेमाफोर में गिनती के लिए कई मान होते हैं।
यह समझना महत्वपूर्ण है कि सेमाफोर काउंटर उन कार्यों की संख्या पर नज़र रखता है जिन्हें ब्लॉक नहीं करना है, यानी वे प्रगति कर सकते हैं। कार्य ब्लॉक करते हैं, और काउंटर शून्य होने पर ही खुद को सेमीफोर की सूची में जोड़ते हैं। इसलिए, एक कार्य P () दिनचर्या में सूची में जुड़ जाता है यदि यह प्रगति नहीं कर सकता है, और V () दिनचर्या का उपयोग करके "मुक्त" किया जाता है।
अब, यह देखना काफी स्पष्ट है कि बाइनरी सेमाफोर का उपयोग कैसे किया जा सकता है ताकि सिंक्रोनाइजेशन और आपसी बहिष्कार को हल किया जा सके - वे अनिवार्य रूप से ताले हैं।
पूर्व। तादात्म्य:
thread A{
semaphore &s; //locks/semaphores are passed by reference! think about why this is so.
A(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
;// some block of code B2
...
}
//thread B{
semaphore &s;
B(semaphore &s): s(s){} //constructor
foo(){
...
...
// some block of code B1
s.V();
..
}
main(){
semaphore s(0); // we start the semaphore at 0 (closed)
A a(s);
B b(s);
}
उपरोक्त उदाहरण में, बी 1 निष्पादन समाप्त होने के बाद ही बी 2 निष्पादित कर सकता है। मान लीजिए कि थ्रेड A पहले निष्पादित होता है - sem.P () में जाता है, और प्रतीक्षा करता है, क्योंकि काउंटर 0 (बंद) है। थ्रेड बी साथ आता है, बी 1 को खत्म करता है, और फिर थ्रेड ए को मुक्त करता है - जो फिर बी 2 को पूरा करता है। इसलिए हम सिंक्रोनाइज़ेशन हासिल करते हैं।
अब आइए एक बाइनरी सेमाफोर के साथ आपसी बहिष्कार को देखें:
thread mutual_ex{
semaphore &s;
mutual_ex(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
//critical section
s.V();
...
...
s.P();
//critical section
s.V();
...
}
main(){
semaphore s(1);
mutual_ex m1(s);
mutual_ex m2(s);
}
पारस्परिक बहिष्करण काफी सरल है - m1 और m2 एक ही समय में महत्वपूर्ण अनुभाग में प्रवेश नहीं कर सकते हैं। इसलिए प्रत्येक थ्रेड अपने दो महत्वपूर्ण खंडों के लिए पारस्परिक बहिष्करण प्रदान करने के लिए एक ही सेमीफोर का उपयोग कर रहा है। अब, क्या अधिक संगाम होना संभव है? महत्वपूर्ण वर्गों पर निर्भर करता है। (इस बारे में सोचें कि आपसी बहिष्कार हासिल करने के लिए कोई और कैसे सेमाफोर का उपयोग कर सकता है .. संकेत संकेत: क्या मुझे केवल एक सेमाफोर का उपयोग करने की आवश्यकता है?)
सेमाफोर की गणना: एक सेमाफोर जिसमें एक से अधिक मूल्य होते हैं। आइए देखें कि यह किसका अर्थ है - एक से अधिक मूल्य वाला ताला ?? इतना खुला, बंद, और ... हम्म। आपसी बहिष्करण या तुल्यकालन में बहु-चरण-लॉक का उपयोग क्या है?
चलो दो का आसान लेते हैं:
एक गिनती के सेमाफोर का उपयोग करके सिंक्रनाइज़ेशन: मान लीजिए कि आपके पास 3 कार्य हैं - # 1 और 2 जिसे आप 3 के बाद निष्पादित करना चाहते हैं। आप अपने सिंक्रनाइज़ेशन को कैसे डिज़ाइन करेंगे?
thread t1{
...
s.P();
//block of code B1
thread t2{
...
s.P();
//block of code B2
thread t3{
...
//block of code B3
s.V();
s.V();
}
इसलिए यदि आपका सेमाफोर बंद होने लगे, तो आप सुनिश्चित करें कि t1 और t2 ब्लॉक, सेमीफोर की सूची में जुड़ जाएं। फिर सभी महत्वपूर्ण t3 के साथ आता है, अपने व्यवसाय को समाप्त करता है और t1 और t2 को मुक्त करता है। उन्हें किस क्रम में मुक्त किया जाता है? सेमाफोर की सूची के कार्यान्वयन पर निर्भर करता है। FIFO हो सकता है, कुछ विशेष प्राथमिकता पर आधारित हो सकता है, आदि। (नोट: इस बारे में सोचें कि आप अपने पी और वी की व्यवस्था कैसे करेंगे? यदि आप चाहते थे कि t1 और t2 को किसी विशेष क्रम में क्रियान्वित किया जाए, और यदि आप अर्धवृत्त के कार्यान्वयन के बारे में नहीं जानते थे)
(पता करें: यदि वी की संख्या पी के संख्या से अधिक है तो क्या होगा?)
मतगणना सेमाफोर का उपयोग करके आपसी बहिष्कार: मैं आपको इसके लिए अपना खुद का छद्म कोड बनाना चाहता हूं (आपको चीजों को बेहतर तरीके से समझाता है!) - लेकिन मौलिक अवधारणा यह है: काउंटर की गिनती का सेमाफोर = एन एन कार्यों को महत्वपूर्ण रूप से स्वतंत्र रूप से प्रवेश करने की अनुमति देता है! । इसका मतलब यह है कि आपके पास एन कार्य हैं (या थ्रेड्स, यदि आप पसंद करते हैं) महत्वपूर्ण अनुभाग में प्रवेश करते हैं, लेकिन एन + 1 वां कार्य अवरुद्ध हो जाता है (हमारी पसंदीदा अवरुद्ध-कार्य सूची पर चला जाता है), और केवल तब तक जाने दिया जाता है जब कोई व्यक्ति वी का अर्धचंद्राकार होता है कम से कम एक बार। तो सेमीफोर काउंटर, 0 और 1 के बीच झूलने के बजाय, अब 0 और N के बीच चला जाता है, N कार्यों को स्वतंत्र रूप से प्रवेश करने और बाहर निकलने की अनुमति देता है, जिससे कोई भी अवरुद्ध नहीं होता है!
अब गश, तुम्हें इस तरह की बेवकूफी की जरूरत क्यों होगी? एक से अधिक लोगों को एक संसाधन का उपयोग न करने के लिए आपसी बहिष्कार का पूरा बिंदु नहीं है ?? (संकेत संकेत ... आपके कंप्यूटर में आपके पास केवल एक ड्राइव नहीं है, क्या आप ...?)
के बारे में सोचने के लिए : क्या परस्पर बहिष्करण को केवल एक गिनती के सेमाफोर होने से प्राप्त किया जाता है? क्या होगा अगर आपके पास संसाधन के 10 उदाहरण हैं, और 10 धागे आते हैं (गिनती के सेमाफोर के माध्यम से) और पहले उदाहरण का उपयोग करने का प्रयास करें?
एक सेमाफोर एक प्राकृतिक संख्या युक्त एक वस्तु है (यानी एक पूर्णांक से अधिक या शून्य के बराबर) जिस पर दो संशोधित संचालन परिभाषित होते हैं। एक ऑपरेशन, V
प्राकृतिक में 1 जोड़ता है। अन्य ऑपरेशन, P
प्राकृतिक संख्या को 1. घटाता है। दोनों गतिविधियां परमाणु हैं (अर्थात किसी भी अन्य ऑपरेशन को एक ही समय में निष्पादित नहीं किया जा सकता V
हैP
)।
चूँकि प्राकृतिक संख्या 0 को कम नहीं किया जा सकता है, इसलिए P
0 से युक्त एक सेमाफ़ोर पर कॉल करना कॉलिंग प्रक्रिया (/ थ्रेड) के निष्पादन को रोक देगा, जब तक कि कुछ क्षण जिस पर संख्या 0 नहीं है औरP
सफलतापूर्वक (और atomically) निष्पादित की जा सकती है।
जैसा कि अन्य उत्तरों में उल्लेख किया गया है, किसी निश्चित संसाधन तक पहुँच को अधिकतम (लेकिन चर) प्रक्रियाओं तक सीमित करने के लिए सेमाफोर का उपयोग किया जा सकता है।
मैंने विज़ुअलाइज़ेशन बनाया है जो विचार को समझने में मदद करना चाहिए। मल्टीफ़्रेड वातावरण में एक सामान्य संसाधन तक पहुँच को सेमाफोर नियंत्रित करता है।
ExecutorService executor = Executors.newFixedThreadPool(7);
Semaphore semaphore = new Semaphore(4);
Runnable longRunningTask = () -> {
boolean permit = false;
try {
permit = semaphore.tryAcquire(1, TimeUnit.SECONDS);
if (permit) {
System.out.println("Semaphore acquired");
Thread.sleep(5);
} else {
System.out.println("Could not acquire semaphore");
}
} catch (InterruptedException e) {
throw new IllegalStateException(e);
} finally {
if (permit) {
semaphore.release();
}
}
};
// execute tasks
for (int j = 0; j < 10; j++) {
executor.submit(longRunningTask);
}
executor.shutdown();
उत्पादन
Semaphore acquired
Semaphore acquired
Semaphore acquired
Semaphore acquired
Could not acquire semaphore
Could not acquire semaphore
Could not acquire semaphore
लेख से नमूना कोड
एक हार्डवेयर या सॉफ्टवेयर फ्लैग। मल्टी टास्किंग सिस्टम में, एक सेमाफोर एक वैल्यू के साथ वैरिएबल होता है, जो एक कॉमन रिसोर्स की स्थिति को दर्शाता है। प्रोसेस के लिए रिसोर्स की जरूरत होती है, सिस्माफोर को रिसोर्स की स्थिति को निर्धारित करने के लिए चेक करता है और फिर तय करता है कि कैसे आगे बढ़ना है।
सेमीफोरर्स थ्रेड लिमिटर्स की तरह काम करते हैं।
उदाहरण: यदि आपके पास 100 धागे का एक पूल है और आप कुछ DB ऑपरेशन करना चाहते हैं। यदि दिए गए समय में 100 थ्रेड्स डीबी तक पहुंचते हैं, तो डीबी में लॉकिंग मुद्दा हो सकता है, इसलिए हम सेमीफोर का उपयोग कर सकते हैं जो एक समय में केवल सीमित थ्रेड की अनुमति देता है। उदाहरण के लिए, एक समय में केवल एक थ्रेड की अनुमति दें। जब कोई थ्रेड acquire()
विधि को कॉल करता है, तो वह एक्सेस प्राप्त करेगा और release()
विधि को कॉल करने के बाद , यह एक्सीलेंस जारी करेगा ताकि अगले थ्रेड को एक्सेस मिल सके।
package practice;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore s = new Semaphore(1);
semaphoreTask s1 = new semaphoreTask(s);
semaphoreTask s2 = new semaphoreTask(s);
semaphoreTask s3 = new semaphoreTask(s);
semaphoreTask s4 = new semaphoreTask(s);
semaphoreTask s5 = new semaphoreTask(s);
s1.start();
s2.start();
s3.start();
s4.start();
s5.start();
}
}
class semaphoreTask extends Thread {
Semaphore s;
public semaphoreTask(Semaphore s) {
this.s = s;
}
@Override
public void run() {
try {
s.acquire();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" Going to perform some operation");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
तो कल्पना कीजिए कि हर कोई बाथरूम जाने की कोशिश कर रहा है और बाथरूम के लिए कुछ निश्चित संख्याएँ हैं। अब यदि पर्याप्त कुंजी नहीं बची है, तो उस व्यक्ति को प्रतीक्षा करने की आवश्यकता है। तो बाथरूम (सिस्टम संसाधनों) के लिए उपलब्ध कुंजियों के उन सेट का प्रतिनिधित्व करने के रूप में सेमाफोर के बारे में सोचें, जो विभिन्न प्रक्रियाओं (बाथरूम जाने वाले) तक पहुंच प्रदान कर सकते हैं।
अब एक ही समय में बाथरूम जाने की कोशिश करने वाली दो प्रक्रियाओं की कल्पना करें। यह एक अच्छी स्थिति नहीं है और इसे रोकने के लिए सेमाफोर का उपयोग किया जाता है। दुर्भाग्य से, सेमाफोर एक स्वैच्छिक तंत्र है और प्रक्रियाएं (हमारे बाथरूम जाने वाले) इसे अनदेखा कर सकते हैं (यानी यदि चाबियाँ हैं, तो भी कोई व्यक्ति अभी भी दरवाजा खोल सकता है)।
बाइनरी / म्यूटेक्स और काउंटिंग सेमाफोर के बीच भी अंतर हैं।
Http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html पर व्याख्यान नोट्स देखें ।
यह एक पुराना प्रश्न है, लेकिन सेमाफोर के सबसे दिलचस्प उपयोगों में से एक एक रीड / राइट लॉक है और इसका स्पष्ट उल्लेख नहीं किया गया है।
R / w ताले सरल शैली में काम करते हैं: एक पाठक के लिए एक परमिट और लेखकों के लिए सभी परमिट का उपभोग करते हैं। दरअसल, ar / w लॉक का एक तुच्छ कार्यान्वयन लेकिन रीड (वास्तव में दो बार) पर मेटाडेटा संशोधन की आवश्यकता होती है जो एक बोतल गर्दन बन सकती है, फिर भी एक म्यूटेक्स या लॉक की तुलना में काफी बेहतर है।
एक और नकारात्मक पहलू यह है कि लेखकों को आसानी से शुरू किया जा सकता है जब तक कि अर्धकुम्भ एक निष्पक्ष नहीं होता है या लेखन कई अनुरोधों में परमिट प्राप्त करता है, ऐसे में उन्हें अपने बीच एक स्पष्ट म्यूटेक्स की आवश्यकता होती है।
आगे पढ़ें :
एक सेमाफोर एक संसाधन को लॉक करने का एक तरीका है ताकि यह गारंटी दी जाए कि कोड का एक टुकड़ा निष्पादित किया जाता है, केवल उस कोड के टुकड़े तक उस संसाधन तक पहुंच होती है। यह एक संसाधन को समवर्ती रूप से दो थ्रेड रखता है, जिससे समस्याएं हो सकती हैं।