Ace VS Boost VS Poco

ACE vs Boost vs POCO

As rdbound said, Boost has a "near STL" status. So if you don't need another library, stick to Boost. However, I use POCO because it has some advantages for my situation. The good things about POCO IMO:

  • Better thread library, especially a Active Method implementation. I also like the fact that you can set the thread priority.

  • More comprehensive network library than boost::asio. However boost::asio is also a very good library.

  • Includes functionality that is not in Boost, like XML and database interface to name a few.

  • It is more integrated as one library than Boost.

  • It has clean, modern and understandable C++ code. I find it far easier to understand than most of the Boost libraries (but I am not a template programming expert :)).

  • It can be used on a lot of platforms.

Some disadvantages of POCO are:

  • It has limited documentation. This somewhat offset by the fact that the source is easy to understand.

  • It has a far smaller community and user base than, say, Boost. So if you put a question on Stack Overflow for example, your chances of getting an answer are less than for Boost

  • It remains to be seen how well it will be integrated with the new C++ standard. You know for sure that it will not be a problem for Boost.

I never used ACE, so I can't really comment on it. From what I've heard, people find POCO more modern and easier to use than ACE.

Some answers to the comments by Rahul:

  1. I don't know about versatile and advanced. The POCO thread library provides some functionality that is not in Boost: ActiveMethod and Activity, and ThreadPool. IMO POCO threads are also easier to use and understand, but this is a subjective matter.

  2. POCO network library also provides support for higher level protocols like HTTP and SSL (possibly also in boost::asio, but I am not sure?).

  3. Fair enough.

  4. Integrated library has the advantage of having consistent coding, documentation and general "look and feel".

  5. Being cross-platform is an important feature of POCO, this is not an advantage in relation to Boost.

Again, you should probably only consider POCO if it provides some functionality you need and that is not in Boost.

ACE vs Boost vs Poco vs wxWidgets

I have used parts of POCO now and again and found it to be a very nice lib. I largely abandoned ACE a number of years ago but POCO contains some of the same patterns - Task, Reactor, etc. I have never had any problems with it so I have to assume it is stable.

Some aspects that I like:

  • it is a pretty well integrated OOP hierarchy so the components work well with each other. It has a much more cohesive feel than something like Boost which is rather piece-meal.

  • the source code is available and very clear. You don't need to devote large blocks of time to understand what it is doing (ACE, at least last I looked at the source) or be a template wizard (Boost).

  • Components stick close to standard C++. Exceptions are derived from std::exception; they didn't reinvent yet-another-string class, etc.

  • It is surprising comprehensive. There is a lot more there than appears at first glance.

The downside:

  • A matter of personal preference but the authors stick pretty much to a one class per header file model so you end up including a lot of different files.

  • Limited documentation. Mostly doxygen type API pages and a couple of PDFs pointing to source examples. It's usable but considering the size of the lib it is initially difficult to figure if you are making the best use of the components.

  • If there is an active community built around it, I never found it. The package is maintained by some European based company and they had a wiki but I didn't find it that active or useful.

All things considered, the downside is pretty minor. I think it is a very good library and would definitely recommend it.

Replacing ACE with BOOST

ACE_Semaphore & ACE_THREAD & ACE_Condition

The above are all part of boost::threads

http://www.boost.org/doc/libs/1_52_0/doc/html/thread.html

C++11
http://en.cppreference.com/w/cpp/thread

ACE_OS

Some common things are done in boost w.r.t. OS but it depends on what parts of this you are using. There is boost::system and boost::filesystem, threading above and many more. Some of the lower level calls you'll need to handle I suspect.

http://www.boost.org/doc/libs/1_52_0/libs/system/doc/index.html

http://www.boost.org/doc/libs/1_52_0/libs/filesystem/doc/index.htm

ACE_Timer

boost::asio can be used to create timers which are similar to this and this lib may provide more of the function of ACE (or the mechanisms to create it)

http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio.html

ACE_Hash

ACE_Hash - again there is a lot of function here, but it could be replaced/implemented with boost or C++11

Boost:
http://www.boost.org/doc/libs/1_52_0/doc/html/hash.html

http://www.boost.org/doc/libs/1_52_0/doc/html/unordered.html

c++11:
http://en.cppreference.com/w/cpp/container/unordered_map

ACE_Task_Base

I would suspect you'll need to create your own replacement for the functionality here. The messages and message parsing mechanisms are quite involved in ACE. Threading is covered above, but a manager for created threads again is likely to need implementing.

Multiple Http Servers with Poco and Boost C++

HttpServerApplication is not designed to be used in this way. It's designed to be a singleton.

http://pocoproject.org/docs/Poco.Util.ServerApplication.html

You can fix that part by not deriving from ServerApplication in your HttpServer class. After all, you want multiple servers, not applications.

In my simplest test, the following works:

#include <Poco/Net/HTMLForm.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/ServerSocket.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Util/ServerApplication.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>

boost::asio::io_service service(100);

class RequestHandler : public Poco::Net::HTTPRequestHandler {
public:
RequestHandler(){}
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response){}
};

class RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
RequestHandlerFactory(){}
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request)
{
return new RequestHandler();
}
};

class HttpServer : public boost::enable_shared_from_this<HttpServer>{

Poco::Net::ServerSocket svs;
Poco::Net::HTTPServer srv;

public:
HttpServer(std::string address_, Poco::UInt16 port_):
svs(Poco::Net::SocketAddress(address_.empty() ? "127.0.0.1" : address_, port_)),
srv(new RequestHandlerFactory(), svs, new Poco::Net::HTTPServerParams)
{
svs.setReuseAddress(true);
svs.setReusePort(true);
}

virtual ~HttpServer(){}

void start()
{
service.post(
boost::bind(&HttpServer::exec, shared_from_this()));
}

void stop()
{
srv.stop();
}

private:
void exec()
{
srv.start();
}
};

In main, I create a subclass of ServerApplication for the sole reason of claling the protected method waitForTerminationRequest() before exit of main. If you need argument parsing, of course pass argc, argv to app.run. But at this point I don't see the need.

int main() {
struct App : Poco::Util::ServerApplication {
~App() {
waitForTerminationRequest();
}
} app;

for (int i=0; i<2; ++i) {
boost::make_shared<HttpServer>("", 8080+i)->start();
}
}

OLD ANSWER TEXT

How are you instantiating the HttpServer objects?

  1. You should, obviously, use boost::make_shared<HttpServer>(host, port) (or shared_ptr<HttpServer>(new HttpServer(host, port))) for enable_shared_from_this to be allowed. Don't forget to hold on to the shared ptr at least until the service has been started (by posting it's exec() call to io_service).

    Specifically, this is illegal:

    for (int i=0; i<10; ++i) {
    HttpServer s("", 8080+i);
    s.start();
    }

    Instead, use e.g.

    for (int i=0; i<10; ++i) {
    boost::make_shared<HttpServer>("", 8080+i)->start();
    }
  2. Also, if you're going to run it on a pool of 100 threads, you need to either use a strand (for a logical thread of execution) or lock the HttpServer object before you use it on any thread.

    • Why do I need strand per connection when using boost::asio?

C++ cross platform for processes: is POCO lib good? other alternatives?

I don't have any direct experience with the Processes lib in POCO but I'm a big fan of the project in general and the networking and threading libs in particular. Works great under Windows (MinGW & VS), OS X, and Linux.

boost vs ACE C++ cross platform performance comparison?

Neither library should really have any overhead compared to using native OS threading facilities. You should be looking at which API is cleaner. In my opinion the boost thread API is significantly easier to use.

ACE tends to be more "classic OO", while boost tends to draw from the design of the C++ standard library. For example, launching a thread in ACE requires creating a new class derived from ACE_Task, and overriding the virtual svc() function which is called when your thread runs. In boost, you create a thread and run whatever function you want, which is significantly less invasive.



Related Topics



Leave a reply



Submit