SObjectizer:简化C++并发编程的强大工具
项目介绍
SObjectizer是一款跨平台的开源C++“actor框架”,旨在显著简化C++中并发和多线程应用程序的开发。它不仅支持Actor模型,还支持发布-订阅模型和类似CSP的通道。SObjectizer允许将并发应用程序创建为一组通过异步消息相互交互的代理对象,处理消息分发并为消息处理提供工作上下文。
项目技术分析
SObjectizer的核心技术包括:
- Actor模型:通过代理对象(agents)实现并发编程,代理对象之间通过异步消息进行通信。
- 发布-订阅模型:支持多生产者/多消费者消息盒,消息发送给该消息盒后,所有订阅者都会收到该消息。
- CSP-like通道:提供类似CSP(Communicating Sequential Processes)的通道,简化并发任务之间的通信。
- 多种调度器:提供多种现成的调度器,允许用户根据需求调整消息分发和工作上下文。
项目及技术应用场景
SObjectizer适用于以下场景:
- 多线程代理服务器:通过代理对象实现并发处理请求,提高服务器性能。
- 自动控制系统:利用发布-订阅模型实现传感器数据的分发和处理。
- 消息队列代理(MQ-broker):支持高效的消息传递和处理,适用于分布式系统中的消息队列。
- 数据库服务器:通过并发处理提高数据库服务器的响应速度和吞吐量。
项目特点
- 成熟稳定:SObjectizer基于1995-2000年的思想,自2002年以来一直在开发,SObjectizer-5自2010年以来持续演进,广泛应用于生产环境。
- 跨平台:支持Windows、Linux、FreeBSD、macOS和Android等多个操作系统。
- 易用性:提供易于理解的API,并附带大量示例和详细的项目Wiki文档。
- 免费开源:采用BSD-3-CLAUSE许可证,可免费用于开发商业软件。
- 不同于TBB、taskflow或HPX:SObjectizer专注于并发计算,而非并行计算,适用于简化多任务并发处理。
代码示例
HelloWorld示例
#include <so_5/all.hpp>
class hello_actor final : public so_5::agent_t {
public:
using so_5::agent_t::agent_t;
void so_evt_start() override {
std::cout << "Hello, World!" << std::endl;
// 结束示例工作
so_deregister_agent_coop_normally();
}
};
int main() {
// 启动SObjectizer
so_5::launch([](so_5::environment_t & env) {
// 在新合作中添加hello_actor实例
env.register_agent_as_coop( env.make_agent<hello_actor>() );
});
return 0;
}
Ping-Pong示例
#include <so_5/all.hpp>
struct ping {
int counter_;
};
struct pong {
int counter_;
};
class pinger final : public so_5::agent_t {
so_5::mbox_t ponger_;
void on_pong(mhood_t<pong> cmd) {
if(cmd->counter_ > 0)
so_5::send<ping>(ponger_, cmd->counter_ - 1);
else
so_deregister_agent_coop_normally();
}
public:
pinger(context_t ctx) : so_5::agent_t{std::move(ctx)} {}
void set_ponger(const so_5::mbox_t mbox) { ponger_ = mbox; }
void so_define_agent() override {
so_subscribe_self().event( &pinger::on_pong );
}
void so_evt_start() override {
so_5::send<ping>(ponger_, 1000);
}
};
class ponger final : public so_5::agent_t {
const so_5::mbox_t pinger_;
int pings_received_{};
public:
ponger(context_t ctx, so_5::mbox_t pinger)
: so_5::agent_t{std::move(ctx)}
, pinger_{std::move(pinger)}
{}
void so_define_agent() override {
so_subscribe_self().event(
[this](mhood_t<ping> cmd) {
++pings_received_;
so_5::send<pong>(pinger_, cmd->counter_);
});
}
void so_evt_finish() override {
std::cout << "pings received: " << pings_received_ << std::endl;
}
};
int main() {
so_5::launch([](so_5::environment_t & env) {
env.introduce_coop([](so_5::coop_t & coop) {
auto pinger_actor = coop.make_agent<pinger>();
auto ponger_actor = coop.make_agent<ponger>(
pinger_actor->so_direct_mbox());
pinger_actor->set_ponger(ponger_actor->so_direct_mbox());
});
});
return 0;
}
Pub/Sub示例
#include <so_5/all.hpp>
using namespace std::literals;
struct acquired_value {
std::chrono::steady_clock::time_point acquired_at_;
int value_;
};
class producer final : public so_5::agent_t {
const so_5::mbox_t board_;
so_5::timer_id_t timer_;
int counter_{};
struct acquisition_time final : public so_5::signal_t {};
void on_timer(mhood_t<acquisition_time>) {
// 向所有消费者发布下一个值
so_5::send<acquired_value>(
board_, std::chrono::steady_clock::now(), ++counter_);
}
public:
producer(context_t ctx, so_5::mbox_t board)
: so_5::agent_t{std::move(ctx)}
, board_{std::move(board)}
{}
void so_define_agent() override {
so_subscribe_self().event(&producer::on_timer);
}
void so_evt_start() override {
// 代理将定期接收acquisition_time信号,无初始延迟,周期为750ms
timer_ = so_5::send_periodic<acquisition_time>(*this, 0ms, 750ms);
}
};
class consumer final : public so_5::agent_t {
const so_5::mbox_t board_;
const std::string name_;
void on_value(mhood_t<acquired_value> cmd) {
std::cout << name_ << ": " << cmd->value_ << std::endl;
}
public:
consumer(context_t ctx, so_5::mbox_t board, std::string name)
: so_5::agent_t{std::move(ctx)}
, board_{std::move(board)}
, name_{std::move(name)}
{}
void so_define_agent() override {
so_subscribe(board_).event(&consumer::on_value);
}
};
int main() {
so_5::launch([](so_5::environment_t & env) {
auto board = env.create_mbox();
env.introduce_coop([board](so_5::coop_t & coop) {
coop.make_agent<producer>(board);
coop.make_agent<consumer>(board, "first"s);
coop.make_agent<consumer>(board, "second"s);
});
std::this_thread::sleep_for(std::chrono::seconds(4));
env.stop();
});
return 0;
}
总结
SObjectizer凭借其成熟稳定的技术、跨平台支持、易用性和免费开源的特点,成为C++并发编程的理想选择。无论是开发多线程代理服务器、自动控制系统,还是消息队列代理和数据库服务器,SObjectizer都能提供强大的支持。立即尝试SObjectizer,体验其简化并发编程的强大功能!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



