我注意到boost並沒有支持信號量。達到類似效果的最簡單方法是什麼?如何在C++中使用boost來實現類似於信號量的功能?
回答
您需要Boost Interprocess semaphore或Boost Thread synchronization原語。
Mutex/Lock和condition是通常用於同步跨單個進程的多個線程訪問共享資源的原語。有exclusive,readers-writer和recursive/reentrant類型的互斥。換句話說,互斥鎖是獨佔鎖。當需要解鎖互斥體並等待對象改變時,條件用於實現原子性。當你開始等待一個條件時,它解鎖互斥並保證不會解鎖+等待調用是原子的,其他線程無法修改這兩個操作之間的資源。
信號量在另一種情況下是條件和互斥量的混合,並且用於完全相同的目的,但同步跨進程的訪問。
也有這樣的事情,如non-blocking/lock-free synchronization這些日子變得非常流行。我個人在高頻交易應用中使用它,因爲數據量相對較大,低延遲確實很重要。
在你的情況下,我假設有5個哲學家可以在5個線程的單個進程中進行晚餐。在這種情況下,你必須使用互斥量,而不是信號量。你可能會也可能不會使用條件。這取決於你想要實現該餐飲程序的確切程度和準確程度。
我不知道如何更好地描述它,因爲我最終會寫一本關於它的書。所以我建議你找一些已經寫好的書來理解基本概念。一旦您瞭解了基本知識,您就可以使用像POSIX threads,Boost Interprocess或Thread,ACE或甚至non-blocking algorithms這樣的API /庫/框架來實現您想要的功能。
祝你好運!
所以,出於好奇,「進程間信號量」這個名稱表明它意味着在進程之間而不是線程之間共享。這是否意味着它會在理論上使用一個introprocess信號量的前提下花費額外的開銷?我不確定如何輕鬆地將線程條件用於應用程序,例如我對該問題的評論中提到的玩具應用程序。 – jonderry 2010-10-14 00:51:21
@jonderry:好的,我想我可以用一個簡單的答案逃脫,但你得到了我。我已經開始在評論中回覆,但由於鏈接太多,所以我最終編輯了我的答案。請參閱更新的版本。謝謝。 – 2010-10-14 02:14:57
謝謝,弗拉德。誠然,餐飲哲學家的問題在相鄰的叉子上使用互斥體,但如果不添加更多的東西,就會陷入僵局。解決這個問題的一個標準方法是隻允許4位哲學家同時用餐,這樣人們總是可以取得進步。實現這一目標的自然方法是使用信號量。 – jonderry 2010-10-14 03:02:39
這是一種使用Boost.Thread實現非常簡單的信號量的方法。這是一個線程間信號量,而不是一個進程間信號量。沒有暗示的保證等 - 我甚至沒有編寫代碼。它演示了互斥鎖和條件變量是如何相互作用的,並且假設了一個合理的Boost最近版本。
注意互斥鎖和條件變量是如何「配對」的 - 線程必須鎖定互斥鎖以等待條件變量,並在被喚醒時重新獲取鎖。此外,更改數據的代碼需要明確地喚醒可能正在等待的其他代碼。這意味着互斥量,條件變量,數據和引起喚醒的條件都緊密耦合。緊密耦合還意味着數據,互斥鎖和條件變量應儘可能封裝 - 任何外部修改都可能以奇怪的方式破壞代碼,包括死鎖,錯過的喚醒和其他奇怪的錯誤。
所有這些實際上意味着作爲對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_;
}
};
我做了一個信號燈類提升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. iPhone:如何使用modalView實現類似於popToRootViewController的功能?
- 3. 如何在C++程序中實現類似於linux/proc/version的功能?
- 4. 在JS和C++應用程序之間實現類信號量功能
- 5. boost如何實現信號和插槽?
- 6. 如何實現全局信號量類
- 7. 如何實現類似於Microsoft Excel的「記錄宏」功能?
- 8. 如何實現類似於Photoshop的「修補工具」功能?
- 9. 我們如何使用getstream實現類似功能的hashtag
- 10. 在Scala中實現類似於LINQ的功能
- 11. 如何在TPL中實現與BlockingCollection類似的功能?
- 12. 如何在php中實現類似Angular的過濾器功能?
- 13. 如何在React Native中實現類似CoordinatorLayout的功能?
- 14. 如何在命令行中實現Siri/Cortana類似的功能?
- 15. 使用unix系統調用在C程序中實現類似shell的功能
- 16. 如何在java中實現類似於Excel中的Web查詢功能?
- 17. null實現類型爲boost ::功能
- 18. 如何在C中實現我自己的信號量?
- 19. 如何使用文件系統實現信號量類
- 20. 實現類似Google+圈子的功能
- 21. 如何使用所有型號類似的功能在Django
- 22. 在C++中使用condition_variable實現信號量11
- 23. 實現類似於非可修改類型的功能
- 24. 如何使用CONCAT或任何類似的功能實現這一類輸出
- 25. 如何實現類似Spotify的iOS應用側邊欄功能
- 26. mongo db - 用於在webapp中實現相似功能的模式
- 27. 如何在Java中實現二進制信號量類?
- 28. 如何使用boost模板相關信號成員實現模板類?
- 29. 實現信號量
- 30. 實現信號量
您能否更具體地瞭解您要查找的行爲?鑑於人們已經提出了大約14種不同類型的信號量。 – jalf 2010-10-14 00:08:42
現在,例如,通過將用餐人數限制在4以下來解決用餐哲學家的問題(通過5位哲學家),通過信號量,我可以將初始值設爲4,哲學家等待信號量並完成信號。 – jonderry 2010-10-14 00:29:27