用asio擼了一個簡單的Actor模型
blog文章地址:http://godebug.org/index.php/archives/139/
前幾天買了本七週七併發模型,看了裡面關於Actor模型的介紹後覺得Actor這東西其實挺簡單的,平時用asio寫網路應用,每個session直接也是通過投遞非同步事件來互相交流的,本質上每個session類也就是一個Actor,看來著東西平時一直在用,只是不知道叫這麼個名字罷了,再生搬硬套一個Actor模型感覺毫無意義,於是用asio寫了個簡單的比較通用的Actor模型。
#include <iostream>
#include <deque>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
template<typename T>
class Actor : public boost::enable_shared_from_this<Actor<T>>
{
public:
Actor(boost::asio::io_service& service)
:service_(service)
{}
~Actor()
{
std::cout << "destroy" << std::endl;
}
void push_message(const T& msg)
{
bool is_runing = !msg_queue_.empty();
msg_queue_.push_back(msg);
if (!is_runing)
{
get_message();
}
}
protected:
void get_message()
{
service_.post(boost::bind(&Actor<T>::do_get_message, shared_from_this()));
}
virtual void process_message(const T& msg) = 0;
private:
void do_get_message()
{
process_message(msg_queue_.front());
msg_queue_.pop_front();
if (!msg_queue_.empty())
{
get_message();
}
}
boost::asio::io_service& service_;
std::deque<T> msg_queue_;
};
#include <boost/format.hpp>
class Actor1 : public Actor<int>
{
public:
Actor1(boost::asio::io_service& service)
:Actor<int>(service)
{}
void set_other(boost::shared_ptr<Actor<std::string>> other)
{
other_ = other;
}
protected:
virtual void process_message(const int& msg)
{
auto ptr = other_.lock();
if (ptr)
{
ptr->push_message(boost::str(boost::format("receive: %d") % msg));
}
}
private:
boost::weak_ptr<Actor<std::string>> other_;
};
class Actor2 : public Actor<std::string>
{
public:
Actor2(boost::asio::io_service& service)
:Actor<std::string>(service), num_(0)
{}
void set_other(boost::shared_ptr<Actor<int>> other)
{
other_ = other;
}
protected:
virtual void process_message(const std::string& msg)
{
std::cout << msg << std::endl;
auto ptr = other_.lock();
if (!ptr)
{
return;
}
if (++num_ == 100)
{
std::cout << "finished.." << std::endl;
return;
}
ptr->push_message(num_);
}
private:
int num_;
boost::weak_ptr<Actor<int>> other_;
};
int main()
{
boost::asio::io_service service;
boost::shared_ptr<Actor1> a1(boost::make_shared<Actor1>(service));
boost::shared_ptr<Actor2> a2(boost::make_shared<Actor2>(service));
a1->set_other(a2);
a2->set_other(a1);
a1->push_message(-1);
service.run();
return 0;
}
相信熟悉asio的人一定會覺得這程式碼這程式碼平淡無奇,看樣我之前因為各種宣傳一直把Actor當成解決並行問題的銀彈了。當然因為C++沒有模式匹配之類的語言限制,程式碼看起來比erlang差得很遠也是原因之一。 如果要多執行緒跑的話,要記得給訊息佇列的操作加鎖。
相關文章
- 爽!用golang 手擼了個簡單的貪吃蛇Golang
- 擼一個簡單的MVVM例子MVVM
- 徒手擼一個簡單的RPC框架RPC框架
- 簡單擼了個 GitHub trending 爬取 APIGithubAPI
- 簡單用 Lumen 擼一個 GitHub trending 爬取 APIGithubAPI
- Akka系列(一):Akka簡介與Actor模型模型
- 一個簡單的業務模型請教模型
- 不到一個月用業餘時間擼了個AppAPP
- 跨平臺c++/boost/asio 簡單的HTTP POST請求 客戶端模型C++HTTP客戶端模型
- 使用beego擼了一個社群Go
- TCP/IP模型的一個簡單解釋TCP模型
- ActorLite:一個輕量級Actor模型實現(中)模型
- 通過Dapr實現一個簡單的基於.net的微服務電商系統(六)——一步一步教你如何擼Dapr之Actor服務微服務
- 我編了一個簡單程式(●'◡'●)
- 用 Laravel6.2 擼了一個微信通知推送平臺Laravel
- 用Golang寫了個簡單易用的微信SDKGolang
- 用 Material Design 寫了一個簡單的 API 測試工具Material DesignAPI
- 一個簡單的iptable的應用
- 使用RecyclerView簡單快捷地擼一個直播公屏出來View
- 用Scroller完成一個簡單的ViewPagerViewpager
- 一個簡單的 indexedDB 應用示例Index
- 一個Java的Actor框架:kilimJava框架
- 寫了一個簡單的Linux Shell用來下載檔案Linux
- 【Akka】Actor模型探索模型
- 手把手教你擼一個簡易的 webpackWeb
- 適合C# Actor的訊息執行方式(5):一個簡單的網路爬蟲C#爬蟲
- 用Vue擼一個『A-Z字母滑動檢索選單』Vue
- 用Kotlin+Retrofit+RxKotlin+MVP擼了一個小專案KotlinMVP
- 用 go 實現一個簡單的 mvcGoMVC
- 用java寫一個貪食蛇的簡單AIJavaAI
- 用 webpack 寫一個簡單的 JS SDKWebJS
- 用PHP寫一個簡單的日曆PHP
- 用純 JavaScript 擼一個 MVC 程式JavaScriptMVC
- 單手擼了個springboot+mybatis+druidSpring BootMyBatisUI
- 一起擼個簡單粗暴的Tv應用主介面的網格佈局控制元件(上)控制元件
- 一起擼個簡單粗暴的Tv應用主介面的網格佈局控制元件(下)控制元件
- 用 Vue 建立一個簡單的 electron 桌面應用Vue
- PHP下用Swoole實現Actor併發模型PHP模型