boost :: asio, pools de thread e monitoramento de thread
Eu implementei um pool de threads usandoboost::asio
e algum númeroboost::thread
chamando objetosboost::asio::io_service::run()
. No entanto, um requisito que me foi dado é ter uma maneira de monitorar todos os segmentos para "saúde". Minha intenção é fazer um objeto sentinela simples que possa ser passado através do pool de threads - se ele conseguir passar, então podemos assumir que o thread ainda está processando o trabalho.
No entanto, dada a minha implementação, não sei como (se) posso monitorar todos os threads no pool de forma confiável. Eu simplesmente deleguei a função thread paraboost::asio::io_service::run()
, então postar um objeto sentinela noio_service
instância não garante que segmento vai realmente ter sentinela e fazer o trabalho.
Uma opção pode ser apenas inserir periodicamente o sentinela, e esperar que ele seja escolhido por cada thread pelo menos uma vez em um período de tempo razoável, mas que obviamente não é o ideal.
Tome o seguinte exemplo. Devido à forma como o manipulador é codificado, neste caso, podemos ver que cada thread fará a mesma quantidade de trabalho, mas, na realidade, não terei controle da implementação do manipulador, alguns podem ser longos, enquanto outros serão quase imediato.
#include <iostream>
#include <boost/asio.hpp>
#include <vector>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
void handler()
{
std::cout << boost::this_thread::get_id() << "\n";
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
int main(int argc, char **argv)
{
boost::asio::io_service svc(3);
std::unique_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(svc));
boost::thread one(boost::bind(&boost::asio::io_service::run, &svc));
boost::thread two(boost::bind(&boost::asio::io_service::run, &svc));
boost::thread three(boost::bind(&boost::asio::io_service::run, &svc));
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
svc.post(handler);
work.reset();
three.join();
two.join();
one.join();
return 0;
}