C++ã§Producer-Consumerãã¿ã¼ã³æ¸ãã¦ã¿ã
âãã®æ¬ã®ç¬¬5ç« Producer-Consumerãã¿ã¼ã³ãC++ã§æ¸ãã¦ã¿ãã
å¢è£æ¹è¨ç Javaè¨èªã§å¦ã¶ãã¶ã¤ã³ãã¿ã¼ã³å ¥é ãã«ãã¹ã¬ããç·¨
- ä½è : çµå浩
- åºç社/ã¡ã¼ã«ã¼: ã½ãããã³ã¯ã¯ãªã¨ã¤ãã£ã
- çºå£²æ¥: 2006/03/21
- ã¡ãã£ã¢: 大åæ¬
- è³¼å ¥: 15人 ã¯ãªãã¯: 287å
- ãã®ååãå«ãããã° (203件) ãè¦ã
å¦çã®æµãã¨ãã¦ã¯ãã±ã¼ããä½ã人(ã¹ã¬ãã)ã3人ãã±ã¼ããé£ã¹ã人ã3人ãä½ã£ãã±ã¼ããç½®ãã¦ãããã¼ãã«ã®é¢ç©ãã±ã¼ã3ã¤åãã¨ãã風ã«ãªã£ã¦ãã¾ããé¢åãããã®ã§ãã¡ã¤ã«ã¯åå²ãã¾ããã§ããããæ¬ã®ãµã³ãã«ã¨å¯¾æ¯ã¯ãæããã¨æãã¾ãã
#include <iostream> #include <chrono> #include <atomic> #include <thread> #include <condition_variable> #include <mutex> #include <string> #include <sstream> #include <random> #include <queue> class table { std::mutex mutex_; std::condition_variable condition_; std::queue<std::string> buffer_; const int count_; public: explicit table(int count) : buffer_{}, count_{count} { } table(table const&) = delete; table& operator=(table const&) = delete; void push(std::string const& cake, std::string const& thread_name) { std::unique_lock<std::mutex> lock{mutex_}; while (static_cast<int>(buffer_.size()) >= count_) { condition_.wait(lock); } buffer_.push(cake); condition_.notify_all(); std::cout << thread_name << " puts " << cake << std::endl; } std::string pop(std::string const& thread_name) { std::unique_lock<std::mutex> lock{mutex_}; while (buffer_.empty()) { condition_.wait(lock); } std::string cake = std::move(buffer_.front()); buffer_.pop(); condition_.notify_all(); std::cout << thread_name << " takes " << cake << std::endl; return cake; } }; class cake_maker { table& table_; std::string name_; std::uniform_int_distribution<> rand_; std::mt19937 engine_; static std::atomic<int> id_; public: cake_maker(table& table, std::string name, std::mt19937::result_type seed) : table_{table}, name_{std::move(name)}, rand_{0, 1000}, engine_{seed} { } void operator()() { while (true) { std::this_thread::sleep_for(std::chrono::milliseconds{rand_(engine_)}); std::ostringstream oss; oss << "[cake no." << id_ << "] by " << name_; ++id_; table_.push(oss.str(), name_); } } }; std::atomic<int> cake_maker::id_ = 0; class cake_eater { table& table_; std::string name_; std::uniform_int_distribution<> rand_; std::mt19937 engine_; public: cake_eater(table& table, std::string name, std::mt19937::result_type seed) : table_{table}, name_{std::move(name)}, rand_{0, 1000}, engine_{seed} { } void operator()() { while (true) { std::string const& cake = table_.pop(name_); std::this_thread::sleep_for(std::chrono::milliseconds{rand_(engine_)}); } } }; int main() { table table{10}; std::thread maker1{cake_maker{table, "Maker-1", 31415}}; std::thread maker2{cake_maker{table, "Maker-2", 92653}}; std::thread maker3{cake_maker{table, "Maker-3", 58979}}; std::thread eater1{cake_eater{table, "Eater-1", 32384}}; std::thread eater2{cake_eater{table, "Eater-2", 62643}}; std::thread eater3{cake_eater{table, "Eater-3", 38327}}; maker1.join(); maker2.join(); maker3.join(); eater1.join(); eater2.join(); eater3.join(); }
å®è¡ä¾
Maker-2 puts [cake no.0] by Maker-2 Eater-3 takes [cake no.0] by Maker-2 Maker-2 puts [cake no.1] by Maker-2 Eater-3 takes [cake no.1] by Maker-2 Maker-2 puts [cake no.2] by Maker-2 Eater-2 takes [cake no.2] by Maker-2 Maker-1 puts [cake no.3] by Maker-1 Eater-1 takes [cake no.3] by Maker-1 Maker-3 puts [cake no.4] by Maker-3 Eater-3 takes [cake no.4] by Maker-3 Maker-3 puts [cake no.5] by Maker-3 Eater-3 takes [cake no.5] by Maker-3 Maker-1 puts [cake no.6] by Maker-1 Maker-1 puts [cake no.7] by Maker-1 Eater-2 takes [cake no.6] by Maker-1 Eater-1 takes [cake no.7] by Maker-1 Maker-3 puts [cake no.8] by Maker-3 Maker-2 puts [cake no.9] by Maker-2 ^Cç¶è¡ããã«ã¯ä½ããã¼ãæ¼ãã¦ãã ãã . . .
C++æ¨æºã§ã¹ã¬ããã«ååãã¤ããæ¹æ³ããªãã£ãã®ã§ãè¦èã®çã¨ãã¦ãpush
ã¨pop
ã®å¼æ°ã«ã¹ã¬ããåã渡ãå¼æ°ã追å ãã¾ããã
while (static_cast<int>(buffer_.size()) >= count_) { condition_.wait(lock); }
ã¨
while (buffer_.empty()) {
condition_.wait(lock);
}
ã¯
condition_.wait(lock, [this] { return static_cast<int>(buffer_.size()) < count_; });
ã¨
condition_.wait(lock, [this] { return !buffer_.empty(); })
ã¨ãæ¸ãã¾ãããæ¬ã¨ã®æ¯è¼ãæèãã¦ãwhileã§æ¸ãã¾ããã
https://sites.google.com/site/cpprefjp/article/how_to_use_cv
ã«ã¯not_empty_
ã¨not_full_
ã®2ã¤ã®æ¡ä»¶å¤æ°ã«åããã¦ãã¾ãããä½æ
ãªãã§ããããï¼
1ã¤ã§ãæ£ããåãã¦ãã¨æãã¾ããããããåãããªãã£ãã§ãã
(追è¨ãã¡ããåç §
条件変数 Step-by-Step入門 - yohhoyの日記(別館)
)
ãã®ããã°ã©ã ã¯ç¡éã«ã¼ããªã®ã§ãCtrl + Cãªã©ã§å¼·å¶çµäºãã¦ä¸ããã