Je vous recommande fortement d'utiliser Boost's bibliothèque ASIO
Vous auriez besoin d'une classe d'accepter de nouvelles demandes et une autre pour vérifier périodiquement les mises à jour. Les deux peuvent faire leur travail de manière asynchrone et utiliser le même boost :: asio :: io_service pour planifier le travail.
La configuration serait
- Un réseau asynchrone
boost::asio::ip::tcp::acceptor
l'écoute de nouvelles demandes.
- A
boost::asio::deadline_time
faire une attente asynchrone vérifie les mises à jour de la base de données.
Pseudo code pour ce que je comprends que vous décrivez est ci-dessous:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
class DatabaseUpdateChecker{
public:
DatabaseUpdateChecker(boost::asio::io_service& io, const int& sleepTimeSeconds)
:timer_(io,boost::posix_time::seconds(sleepTimeSeconds)),sleepSeconds_(sleepTimeSeconds){
this->timer_.async_wait(boost::bind(&DatabaseUpdateChecker::doDBUpdateCheck,this,boost::asio::placeholders::error));
};
protected:
void doDBUpdateCheck(const boost::system::error_code& error){
if(!error){
std::cout << " Checking Database for updates" << std::endl;
//Reschdule ourself
this->timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(this->sleepSeconds_));
this->timer_.async_wait(boost::bind(&DatabaseUpdateChecker::doDBUpdateCheck,this,boost::asio::placeholders::error));
}
};
private:
boost::asio::deadline_timer timer_;
int sleepSeconds_;
};
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> TcpSocketPtr;
class NetworkRequest{
public:
NetworkRequest(boost::asio::io_service& io, const int& port)
:acceptor_(io,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port)){
this->start_accept();
};
protected:
void start_accept(){
TcpSocketPtr socketPtr(new boost::asio::ip::tcp::socket(acceptor_.get_io_service()));
std::cout << "About to accept new connection" << std::endl;
acceptor_.async_accept(*socketPtr,boost::bind(&NetworkRequest::handle_accept,this,socketPtr,boost::asio::placeholders::error));
};
void handle_accept(TcpSocketPtr socketPtr,const boost::system::error_code& error){
std::cout << "Accepted new network connection" << std::endl;
if(!error){
std::string response("This is a response\n");
boost::asio::async_write(*socketPtr,boost::asio::buffer(response),
boost::bind(&NetworkRequest::handle_write,this,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
//Start listeing for a new connection
this->start_accept();
}
void handle_write(const boost::system::error_code& error,size_t size){
if(!error){
std::cout << "Wrote out " << size << " bytes to the network connection" << std::endl;
}
}
private:
boost::asio::ip::tcp::acceptor acceptor_;
};
int main(int argc, char *argv[]) {
static const int DB_TIMER_SECONDS=5;
static const int LISTENING_TCP_PORT=4444;
std::cout << "About to start" << std::endl;
boost::asio::io_service io;
DatabaseUpdateChecker dbChecker(io,DB_TIMER_SECONDS);
NetworkRequest networkRequestAcceptor(io,LISTENING_TCP_PORT);
io.run();
std::cout << "This won't be printed" << std::endl;
return 0;
}
Compiler ce qui précède et en cours d'exécution, il montrera que la base de données mise à jour Checker vérifiera les mises à jour toutes les 5 secondes pendant l'écoute des connexions sur Port TCP 4444. Pour voir le code accepter une nouvelle connexion, vous pouvez utiliser telnet/netcat/votre outil client réseau favori ....
telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
This is a response
Connection closed by foreign host.
Si vous trouvez que le traitement des mises à jour et/ou des demandes prend beaucoup de temps alors je regarderais en enfilant votre application et l'exécution de chaque tâche dans son propre fil. io_service va programmer ce qu'il doit faire et ne pas terminer jusqu'à ce qu'il n'y ait plus de travail. L'astuce consiste à faire redéployer les classes lorsqu'elles sont terminées.
Bien sûr, vous devez prendre en compte les commentaires des autres sur votre question. Je ne sais pas comment une interface CORBA pourrait compliquer cela, mais je pense que boost :: asio comme une bibliothèque C++ asynchrone serait une bonne décision et assez flexible pour ce que vous décrivez.
Que diriez-vous d'un programme multi-thread? –
Avez-vous vérifié Boost ASIO? Il y a des E/S synchrones et asynchrones, des temporisations, et plus encore. http://www.boost.org/doc/libs/release/libs/asio/ – Joel
Pour utiliser une approche filetée. Puis-je définir ce thread sur démon comme comment c'est fait en python? Parce que le reste du programme n'a pas besoin de threads comme CORBA. @Joel venir à l'ASIO, s'il vous plaît éclairez-moi. Cela ressemble à une bonne option (j'ai très peu de connaissance d'asio) mais il semble y avoir un appel bloquant à io_service.run(). Je veux exécuter de manière asynchrone la fonction pour dbqueries périodiquement, peu importe ce que le serveur fait. Ils sont plutôt détachés, sauf qu'ils vont partager une variable. Pendant que le serveur continue à fonctionner, l'autre fonction doit s'exécuter de manière asynchrone. – King