我有一个基于websocketpp的服务器(基于ASIO)服务器和一个线程池。我需要分配一些资源(连接到DB等),并确保它们将始终在同一个线程中使用。
所以,这就是我现在所拥有的:
class Server
: public websocketpp::server<websocketpp::config::asio>
{
Server();
//...
static void onMessage(Server * server,
websocketpp::connection_hdl hdl,
Server::message_ptr msg);
//...
};
Server::Server()
{
// ...some initialization routines.. //
set_message_handler(
std::bind(&onMessage,
this,
std::placeholders::_1,
std::placeholders::_2));
listen(port);
start_accept();
}
main()
函数的某处:
Server server;
// estimated thread pool
std::vector<std::thread> threads;
threads.reserve(threadsCount);
for(int i = 0; i < threadsCount; ++i)
{
threads.emplace_back(
[&server]()
{
mongo::Client mongo(config); // !HERE!
server.run();
});
}
正如您可以看到在每个线程中实例化mongo::Client
。我的目标是将ref /指针传递给它(或将来可能添加的任何其他资源)并在Server::onMessage
中接收它(作为附加参数)。
我完全没有想法如何做到这一点。此外,我不想创建像mongo::Client * Server::acquire()
/ Server::release(mongo::Client *)
这样的分配器界面,因为它需要额外的同步。我的目的是访问(如何?)某种类型的每线程&#34; userdata&#34;在Server::onMessage
处理程序中。
答案 0 :(得分:1)
线程本地存储可能有效。
例如,使用struct
来保存您的mongo客户端:
struct ThreadData
{
mongo::Client client;
}
然后,声明一个线程局部ThreadData
对象:
thread_local ThreadData data;
int main( int argc, char* argv[] )
{
Server server;
// estimated thread pool
std::vector<std::thread> threads;
threads.reserve(threadsCount);
for(int i = 0; i < threadsCount; ++i)
{
threads.emplace_back(
[&server]()
{
// 'data' is thread-local
data.client = mongo::Client(config);
server.run();
});
}
}
每个线程都是data
的线程本地副本,因此您可以在Server::onMessage(...)
中访问它而无需进一步同步。
答案 1 :(得分:1)
您可能想看一下WebSocket ++的broadcast_server example。这是一个基本广播公司的实现,它维护一个活动连接列表,其中一个连接发送的任何消息都发送到所有连接。
该示例使用两个线程。主线程处理服务器事件,将它们转换为&#34; actions&#34;添加到队列中的。工作线程(通过thread t(bind(&broadcast_server::process_messages,&server_instance))
创建)处理队列中的操作。
您可以创建多个工作线程,每个线程都有自己的mongo :: Client和任何其他资源,它们从队列中接收消息并处理它们。