Passing io_service to socket in implementation file after initialization in header file
If I initialize an io_service object and a socket object in my header file, how do I pass io_service to the socket as a parameter in my implementation file? Take this header file as an example: // foo.h
#include
class foo { public:
foo(); // Constructor.
private:
boost::asio::io_service ios;
boost::asio::ip::udp::socket sock; };
And the corresponding implementation file: // foo.cc
#include "foo.h"
foo::foo() { sock(ios); // <-- This throws a compiler error. }
Why doing *sock(ios);* doesn't work? What is the proper way to do it? Thank you. Álvaro
Move your initialization of sock into the initialization list. Eg: foo::foo() : sock{ios} {}. Without this, the socket is default constructed without any io service and then you tried to invoke the call operator, not the constructor. On Mon, Jun 18, 2018, 09:13 Álvaro Cebrián Juan via Boost-users < boost-users@lists.boost.org> wrote:
If I initialize an io_service object and a socket object in my header file, how do I pass io_service to the socket as a parameter in my implementation file?
Take this header file as an example:
// foo.h
#include
class foo { public:
foo(); // Constructor.
private:
boost::asio::io_service ios;
boost::asio::ip::udp::socket sock; };
And the corresponding implementation file:
// foo.cc
#include "foo.h"
foo::foo() { sock(ios); // <-- This throws a compiler error. }
Why doing *sock(ios);* doesn't work? What is the proper way to do it?
Thank you.
Álvaro _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
A note of caution.
In all but the most exceptional of cases, you will want one io_service per
application.
Rather than tie the entire application to one instance of a class, which
might make testing difficult, you may want to consider providing the
io_service to the Foo as a dependency injection, with its lifetime
controlled by main().
Example (including the fixed constructor):
#include
On Mon, Jun 18, 2018 at 6:13 AM Álvaro Cebrián Juan via Boost-users
wrote: Why doing sock(ios); doesn't work?
What is the complete error message from the compiler?
Thanks _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
You want one io_service per endpoint, not per application. On Monday, June 18, 2018, Richard Hodges via Boost-users < boost-users@lists.boost.org> wrote:
A note of caution.
In all but the most exceptional of cases, you will want one io_service per application.
Rather than tie the entire application to one instance of a class, which might make testing difficult, you may want to consider providing the io_service to the Foo as a dependency injection, with its lifetime controlled by main().
Example (including the fixed constructor):
#include
class foo { public:
foo(boost::asio::io_service& ios); // Constructor.
private:
boost::asio::io_service& ios;
boost::asio::ip::udp::socket sock; };
foo::foo(boost::asio::io_service& ios) : ios(ios) , sock(ios) { }
int main() { boost::asio::io_service myios;
foo f1(myios); // note - io_service is injected foo f2(myios);
//... generate events etc
myios.run();
// now destroy foos and lastly, myios }
On Mon, 18 Jun 2018 at 15:46, Vinnie Falco via Boost-users < boost-users@lists.boost.org> wrote:
On Mon, Jun 18, 2018 at 6:13 AM Álvaro Cebrián Juan via Boost-users
wrote: Why doing sock(ios); doesn't work?
What is the complete error message from the compiler?
Thanks _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
On Mon, Jun 18, 2018, 14:53 james via Boost-users < boost-users@lists.boost.org> wrote:
You want one io_service per endpoint, not per application.
I think you're confusing io_service with strands. One io_service/context should be able to handle multiple endpoints and even multiple threads running the same io service.
On Monday, June 18, 2018, Richard Hodges via Boost-users < boost-users@lists.boost.org> wrote:
A note of caution.
In all but the most exceptional of cases, you will want one io_service per application.
Rather than tie the entire application to one instance of a class, which might make testing difficult, you may want to consider providing the io_service to the Foo as a dependency injection, with its lifetime controlled by main().
Example (including the fixed constructor):
#include
class foo { public:
foo(boost::asio::io_service& ios); // Constructor.
private:
boost::asio::io_service& ios;
boost::asio::ip::udp::socket sock; };
foo::foo(boost::asio::io_service& ios) : ios(ios) , sock(ios) { }
int main() { boost::asio::io_service myios;
foo f1(myios); // note - io_service is injected foo f2(myios);
//... generate events etc
myios.run();
// now destroy foos and lastly, myios }
On Mon, 18 Jun 2018 at 15:46, Vinnie Falco via Boost-users < boost-users@lists.boost.org> wrote:
On Mon, Jun 18, 2018 at 6:13 AM Álvaro Cebrián Juan via Boost-users
wrote: Why doing sock(ios); doesn't work?
What is the complete error message from the compiler?
Thanks _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
On Mon, Jun 18, 2018 at 11:54 AM james via Boost-users
You want one io_service per endpoint, not per application.
What? No... You're saying a separate io_context for each socket? That's not necessary. These are the common models: * One io_context, one thread: - Implicit strand (no locks needed) * One io_context, multiple threads - Explicit strand needed - Different sockets can process data concurrently * One io_context for each thread - Implicit strand (no locks needed) - Sockets in different contexts can process data concurrently - Passing data between sockets in different contexts requires care (e.g. broadcasts) I know of no benefit to one io_context per socket, nor have I seen an implementation which uses that model. Thanks
No, not per socket. One per port that accepts connections if you're a server, and one per host you're connecting to if you're a client. On Monday, June 18, 2018, Vinnie Falco via Boost-users < boost-users@lists.boost.org> wrote:
On Mon, Jun 18, 2018 at 11:54 AM james via Boost-users
wrote: You want one io_service per endpoint, not per application.
What? No... You're saying a separate io_context for each socket? That's not necessary. These are the common models:
* One io_context, one thread: - Implicit strand (no locks needed)
* One io_context, multiple threads - Explicit strand needed - Different sockets can process data concurrently
* One io_context for each thread - Implicit strand (no locks needed) - Sockets in different contexts can process data concurrently - Passing data between sockets in different contexts requires care (e.g. broadcasts)
I know of no benefit to one io_context per socket, nor have I seen an implementation which uses that model.
Thanks _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
On 19/06/2018 07:34, james wrote:
No, not per socket. One per port that accepts connections if you're a server, and one per host you're connecting to if you're a client.
While you *can* do that, it's unusual and doesn't really provide any particular benefit over the models that Vinnie specified. Essentially, if you make one thread per endpoint then you have the same thing as the "one io_context per thread" model that Vinnie spoke of. If you have multiple independent threadpools per endpoint then you have the combination of the "one io_context per thread" and "one io_context, multiple threads" models (which works, but is still unusual as you start to run into more drawbacks than benefits with this pattern; so I wouldn't recommend it). Otherwise, you have multiple io_contexts per thread, which is a Bad Idea™.
We found a dedicated thread per io_service made things a lot easier. Couple that with your favourite flavour of concurrent queue to keep io async callback code short. Strands seem perfect if you want to kill any scalability so we never even considered patterns that required them. On Tuesday, June 19, 2018, Gavin Lambert via Boost-users < boost-users@lists.boost.org> wrote:
On 19/06/2018 07:34, james wrote:
No, not per socket. One per port that accepts connections if you're a server, and one per host you're connecting to if you're a client.
While you *can* do that, it's unusual and doesn't really provide any particular benefit over the models that Vinnie specified.
Essentially, if you make one thread per endpoint then you have the same thing as the "one io_context per thread" model that Vinnie spoke of.
If you have multiple independent threadpools per endpoint then you have the combination of the "one io_context per thread" and "one io_context, multiple threads" models (which works, but is still unusual as you start to run into more drawbacks than benefits with this pattern; so I wouldn't recommend it).
Otherwise, you have multiple io_contexts per thread, which is a Bad Idea™.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
On 19/06/2018 19:21, james wrote:
We found a dedicated thread per io_service made things a lot easier.
Of course; that's the "one io_context, one thread" model. It's always the easiest to code, but has other tradeoffs.
Strands seem perfect if you want to kill any scalability so we never even considered patterns that required them.
Having separate dedicated threads per X is fine as long as X is relatively small (less than #cpus). It does not scale well. When X surpasses the #cpus, a stranded threadpool usually provides superior performance. If your X is hardcoded then perhaps it's not a big concern, but if it's configurable by the end user, it might be...
participants (6)
-
Gavin Lambert
-
james
-
Richard Hodges
-
Vinnie Falco
-
William Jagels
-
Álvaro Cebrián Juan