मैंने देखा कि बढ़ावा सेफफोर्स का समर्थन नहीं लगता है। समान प्रभाव प्राप्त करने का सबसे आसान तरीका क्या है?सी ++ में बूस्ट का उपयोग करके मैं सैमफोर के समान कुछ कैसे प्राप्त कर सकता हूं?
उत्तर
आपको या तो Boost Interprocess semaphore या Boost Thread synchronization प्राइमेटिव की आवश्यकता है।
Mutex/Lock और condition प्राथमिकताएं हैं जिनका उपयोग आमतौर पर एक ही प्रक्रिया के एकाधिक धागे में साझा संसाधनों तक पहुंच को सिंक्रनाइज़ करने के लिए किया जाता है। exclusive, readers-writer और recursive/reentrant म्यूटेक्स के प्रकार हैं। म्यूटेक्स, दूसरे शब्दों में, एक विशेष लॉक है। जब आप mutex को अनलॉक करने और ऑब्जेक्ट को बदलने की प्रतीक्षा करते हैं तो परमाणुता प्राप्त करने के लिए स्थिति का उपयोग किया जाता है। जब आप किसी शर्त पर प्रतीक्षा करना शुरू करते हैं, तो यह अनलॉक करने के लिए म्यूटेक्स और गारंटी को अनलॉक करता है + प्रतीक्षा करने के लिए कॉल परमाणु है और कोई अन्य थ्रेड उन दो संचालनों के बीच संसाधन को संशोधित नहीं कर सकता है।
सेमफोर, किसी अन्य मामले पर, हालत और म्यूटेक्स का मिश्रण है, और इसका उपयोग उसी उद्देश्य के लिए किया जाता है लेकिन प्रक्रियाओं में पहुंच को सिंक्रनाइज़ करने के लिए किया जाता है।
Mutex vs Semaphore देखें।
non-blocking/lock-free synchronization जैसी चीज भी है जो इन दिनों बहुत लोकप्रिय हो रही है। मैं व्यक्तिगत रूप से उच्च आवृत्ति व्यापार अनुप्रयोगों में इसका उपयोग करता हूं जब डेटा की मात्रा अपेक्षाकृत बहुत बड़ी होती है और कम विलंबता बहुत मायने रखती है।
आपके मामले में, मुझे लगता है कि 5 दार्शनिक 5 सूत्रों के साथ एक प्रक्रिया के अंदर रात का खाना खा सकते हैं। उस स्थिति में आपको एक म्यूटेक्स का उपयोग करना होगा, न कि सैमफोर। हालांकि आप स्थिति का उपयोग कर सकते हैं या नहीं। यह इस बात पर निर्भर करता है कि आप वास्तव में और वास्तव में उस भोजन प्रक्रिया को कैसे कार्यान्वित करना चाहते हैं।
मुझे यकीन नहीं है कि इसे बेहतर तरीके से कैसे वर्णन किया जाए क्योंकि मैं इसके बारे में एक पुस्तक लिखना समाप्त कर दूंगा। इसलिए मैं आपको कुछ ऐसी पुस्तकें ढूंढने की सलाह दूंगा जो बुनियादी अवधारणाओं को समझने के लिए पहले ही लिखी गई हैं। एक बार जब आप मूल बातें जानते हैं, तो आप POSIX threads, Boost Interprocess या Thread, ACE या non-blocking algorithms जैसे एपीआई/लाइब्रेरी/फ्रेमवर्क जैसे आप चाहते हैं प्राप्त करने के लिए उपयोग कर सकते हैं।
शुभकामनाएं!
तो, जिज्ञासा से बाहर, "इंटरप्रोसेस सेमफोर" नाम से पता चलता है कि यह धागे की बजाय प्रक्रियाओं के बीच साझा किया जाना है। क्या इसका मतलब यह है कि सैद्धांतिक रूप से एक इंट्रोप्रोसेस सेमफोर का उपयोग करने के लिए अतिरिक्त ओवरहेड खर्च होता है? मुझे यकीन नहीं है कि सवाल पर मेरी टिप्पणी में उल्लिखित खिलौना आवेदन जैसे अनुप्रयोगों के लिए थ्रेड स्थितियों का आसानी से उपयोग कैसे करें। – jonderry
@jonderry: ठीक है, मैंने सोचा कि मैं एक साधारण उत्तर से दूर हो सकता हूं, लेकिन तुमने मुझे मिल गया। मैंने एक टिप्पणी में जवाब देना शुरू कर दिया है लेकिन यह बहुत सारे लिंक के साथ बहुत बड़ा था इसलिए मैंने अपना जवाब संपादित करना समाप्त कर दिया। कृपया अद्यतन संस्करण देखें। धन्यवाद। –
धन्यवाद, व्लाद। यह सच है कि डाइनिंग दार्शनिकों की समस्या आसन्न कांटे पर म्यूटेक्स का उपयोग करती है, लेकिन यदि आप कुछ और नहीं जोड़ते हैं, तो आपको डेडलॉक मिलता है। इसे हल करने का एक मानक तरीका केवल 4 दार्शनिकों को एक बार भोजन करने की अनुमति देना है ताकि कोई भी प्रगति कर सके। इसे प्राप्त करने का प्राकृतिक तरीका एक सेमफोर के साथ है। – jonderry
बूस्ट का उपयोग करके यह एक बहुत ही सरल सेमफोर को लागू करने का एक तरीका है। थ्रेड। यह एक इंटर-थ्रेड सेमफोर है, एक इंटरप्रोसेस नहीं। कोई वारंटी लागू नहीं है, आदि - मैंने कोड भी संकलित नहीं किया है। यह दिखाता है कि म्यूटेक्स और हालत चर कैसे बातचीत करते हैं, और बूस्ट के एक उचित हाल के संस्करण को मानते हैं।
ध्यान दें कि म्यूटेक्स और कंडीशन चर "युग्मित" कैसे हैं - थ्रेड के पास म्यूटेक्स को लॉक होना चाहिए ताकि वे कंडीशन वैरिएबल पर प्रतीक्षा कर सकें, और लॉक होने पर लॉक फिर से प्राप्त कर सकें। साथ ही, डेटा को बदलने वाले कोड को अन्य कोड को स्पष्ट रूप से जागृत करने की आवश्यकता होती है जो प्रतीक्षा कर सकते हैं। इसका मतलब है कि म्यूटेक्स, हालत परिवर्तनीय, डेटा, और स्थिति जो जागने का कारण बनती है, सभी निकटता से मिलती हैं। तंग युग्मन का अर्थ यह भी है कि यदि डेटा संभव हो तो डेटा, म्यूटेक्स और कंडीशन वैरिएबल को encapsulated किया जाना चाहिए - किसी भी बाहरी संशोधन कोड को अजीब तरीकों से तोड़ सकता है, जिसमें डेडलॉक्स, मिस्ड वेकअप और अन्य अजीब बग शामिल हैं।
यह सब वास्तव में Vlad Lazarenko के उत्तर के पूरक के रूप में है - सिद्धांत और सिद्धांतों को समझना कम से कम "काम" कोड के रूप में बहु-थ्रेड प्रोग्रामिंग में महत्वपूर्ण है।
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_types.hpp>
class semaphore
{
//The current semaphore count.
unsigned int count_;
//mutex_ protects count_.
//Any code that reads or writes the count_ data must hold a lock on
//the mutex.
boost::mutex mutex_;
//Code that increments count_ must notify the condition variable.
boost::condition_variable condition_;
public:
explicit semaphore(unsigned int initial_count)
: count_(initial_count),
mutex_(),
condition_()
{
}
unsigned int get_count() //for debugging/testing only
{
//The "lock" object locks the mutex when it's constructed,
//and unlocks it when it's destroyed.
boost::unique_lock<boost::mutex> lock(mutex_);
return count_;
}
void signal() //called "release" in Java
{
boost::unique_lock<boost::mutex> lock(mutex_);
++count_;
//Wake up any waiting threads.
//Always do this, even if count_ wasn't 0 on entry.
//Otherwise, we might not wake up enough waiting threads if we
//get a number of signal() calls in a row.
condition_.notify_one();
}
void wait() //called "acquire" in Java
{
boost::unique_lock<boost::mutex> lock(mutex_);
while (count_ == 0)
{
condition_.wait(lock);
}
--count_;
}
};
एक आकर्षण की तरह काम करता है। बहुत बुरा यह अब बूस्ट का हिस्सा नहीं है। कोड के लिए – Thomas
+ 1। गिनती में ग्यूटक्स के लिए कोई बात है? वैसे भी प्राप्त होने पर गिनती "पुरानी" होगी, है ना? – daramarak
सही, वापस लौटने पर गिनती पुरानी होगी। डिबगिंग के अलावा अन्य कारणों के लिए एक सेमफोर की गिनती प्राप्त करना संभवतः आपके प्रोग्राम में एक बग है। –
मैं एक सेमाफोर वर्ग को बूस्ट के साथ संगत TimedLockable
अवधारणा बना, तो यह boost::unique_lock<semaphore>
तरह ताले के साथ प्रयोग किया जा सकता है।यह एक की शास्त्रीय परिभाषा में एक सेमफोर नहीं है, लेकिन इसका उपयोग एक के रूप में किया जा सकता है। फिर भी, उम्मीद है कि यह किसी के लिए उपयोगी हो सकता है।
किसी भी तरह से इसका परीक्षण किया गया, लेकिन बहुत संभावना है कि मैंने कुछ गलत किया। अगर कोई इसे शुद्धता साबित कर सकता है तो अच्छा होगा।
class semaphore
{
private:
semaphore(const semaphore & other);
semaphore & operator = (const semaphore & other);
boost::mutex _mutex;
boost::condition_variable _condVar;
size_t _count;
class wait_predicate
{
private:
const size_t & _countRef;
public:
wait_predicate(const size_t & countRef) : _countRef(countRef) {}
bool operator()() { return _countRef > 0; }
};
// must be used inside a locked scope!
inline wait_predicate getWaitPredicate() const
{
return wait_predicate(_count);
}
public:
semaphore(size_t size): _count(size)
{}
void lock()
{
boost::unique_lock<boost::mutex> local_lock(_mutex);
_condVar.wait(local_lock, getWaitPredicate());
_count--;
}
void unlock()
{
boost::unique_lock<boost::mutex> local_lock(_mutex);
_count++;
_condVar.notify_one();
}
bool try_lock()
{
boost::unique_lock<boost::mutex> local_lock(_mutex);
if (0 == _count)
return false;
_count--;
return true;
}
template <typename Duration>
bool try_lock_for(const Duration & duration)
{
boost::unique_lock<boost::mutex> local_lock(_mutex);
if (!_condVar.wait_for(local_lock, duration, getWaitPredicate()))
return false;
_count--;
return true;
}
template <class TimePoint>
bool try_lock_until(const TimePoint & timePoint)
{
boost::unique_lock<boost::mutex> local_lock(_mutex);
if (!_condVar.wait_until(local_lock, timePoint, getWaitPredicate()))
return false;
_count--;
return true;
}
template <class WaitCriteria>
bool timed_lock(const WaitCriteria & criteria)
{
boost::unique_lock<boost::mutex> local_lock(_mutex);
if (!_condVar.timed_wait(local_lock, criteria, getWaitPredicate()))
return false;
_count--;
return true;
}
};
- 1. बूस्ट :: सिग्नल 2 का उपयोग करके मैं स्लॉट कैसे स्टोर और अग्रेषित कर सकता हूं?
- 2. अमरूद का उपयोग करके मैं यह कैसे कर सकता हूं?
- 3. मैं अपने सी # ऐप में जासूस ++ के समान कार्यक्षमता कैसे प्राप्त कर सकता हूं?
- 4. मैं सी # में GetNextWindow() का उपयोग कैसे कर सकता हूं?
- 5. मैं सी ++ में mysql का उपयोग कैसे कर सकता हूं?
- 6. मैं सी # में डीबग्रेक() का उपयोग कैसे कर सकता हूं?
- 7. मैं इसके मूल्य का उपयोग करके एक प्रमुख नाम (हैश में) कैसे प्राप्त कर सकता हूं?
- 8. टेस्ट/यूनिट, मिनीटेस्ट का उपयोग करके मैं ऑटोटैस्ट में रंगीन आउटपुट कैसे प्राप्त कर सकता हूं?
- 9. मैं कुछ बूस्ट लाइब्रेरी का उपयोग कर std :: find_if और std :: मानचित्र कैसे काम कर सकता हूं?
- 10. रुबी का उपयोग करके रीडायरेक्ट के बाद मैं अंतिम यूआरएल कैसे प्राप्त कर सकता हूं?
- 11. मैं सी # में वेक्टर प्रकार कैसे प्राप्त कर सकता हूं?
- 12. पॉको सी ++ लाइब्रेरी का उपयोग करके, मैं डेटा को थ्रेड में कैसे पास कर सकता हूं?
- 13. मैं सी # में वर्तमान समय कैसे प्राप्त कर सकता हूं?
- 14. मैं अजीब का उपयोग करके क्या कर सकता हूं कि मैं पर्ल में नहीं कर सकता?
- 15. क्या मैं सी ++ में "नेमस्पेस का उपयोग करके" प्रभाव को पूर्ववत कर सकता हूं?
- 16. सी और सी ++ के लिए जीएसओएपी का उपयोग करके मैं अमेज़ॅन एडब्ल्यूएस एस 3 का उपयोग कैसे कर सकता हूं?
- 17. मैं LibGit2Sharp का उपयोग करके गिट रिपॉजिटरी से फ़ाइल बाइनरी डेटा कैसे प्राप्त कर सकता हूं?
- 18. मैं लिनक्स पर सी/सी ++ का उपयोग कर DNS लुकअप कैसे कर सकता हूं?
- 19. एमएस ओपन एक्सएमएल एसडीके का उपयोग करके मैं कुछ छवि डेटा और प्रारूप कैसे प्राप्त कर सकता हूं?
- 20. फेसबुक ग्राफ़ एपीआई का उपयोग करके, मैं किसी पृष्ठ की सामग्री कैसे प्राप्त कर सकता हूं?
- 21. मैं xmllint और XPath का उपयोग करके एक विशेषता से मूल्य कैसे प्राप्त कर सकता हूं?
- 22. आर का उपयोग करके मैं कैसे भेज/प्राप्त कर सकता हूं (एसएमटीपी/पीओपी 3) ईमेल?
- 23. एक्सेलेरोमीटर का उपयोग करके मैं आंदोलन की दिशा कैसे प्राप्त कर सकता हूं?
- 24. मैं जावास्क्रिप्ट में गोटो का उपयोग कैसे कर सकता हूं?
- 25. जीसीसी का उपयोग करके असेंबली आउटपुट के साथ स्रोत लाइन इनलाइन कैसे प्राप्त कर सकता हूं?
- 26. Ember.js का उपयोग करके, दृश्य के बाद मैं कुछ जेएस कैसे चला सकता हूं?
- 27. मैं नए का उपयोग करके सी ++ में सरणी कैसे बना सकता हूं और प्रत्येक तत्व को आरंभ कर सकता हूं?
- 28. मैं बूस्ट :: property_tree :: ptree कैसे विलय/अपडेट कर सकता हूं?
- 29. बूस्ट फीनिक्स का उपयोग करके, मैं start_if कॉल के साथ start_if कॉल कैसे शुरू कर सकता हूं?
- 30. मैं लिस्टबॉक्स में कुछ आइटम कैसे बोल्ड कर सकता हूं?
क्या आप इस व्यवहार के बारे में अधिक विशिष्ट हो सकते हैं कि आप किस व्यवहार की तलाश में हैं? यह देखते हुए कि लोग लगभग 14 विभिन्न प्रकार के सेमफोरों के साथ आए हैं। – jalf
अभी, कुछ ऐसा जो मुझे दे देगा, उदाहरण के लिए, भोजन करने वाले दार्शनिक की समस्या (5 दार्शनिकों के साथ) को अधिकतम 4 खाने वाले लोगों की संख्या सीमित करके हल करें। सेमफोरों के साथ, मैं केवल 4 का प्रारंभिक मान निर्धारित कर सकता हूं और प्रत्येक को दार्शनिक सैद्धांत और सिग्नल पर इंतजार करते हैं जब किया जाता है। – jonderry