Boost logo

Boost Users :

Subject: Re: [Boost-users] [asio] Async (or sync) in threads
From: Michael Powell (mwpowellhtx_at_[hidden])
Date: 2013-07-25 11:10:58


On Thu, Jul 25, 2013 at 2:30 AM, Anthony Foiani <tkil_at_[hidden]> wrote:
> Michael Powell <mwpowellhtx_at_[hidden]> writes:
>
>> Most of the examples are one main being the sole main thread hosting
>> the io_service. Would that this were the case with me. This has to
>> be one worker among several other workers running in the same
>> process.
>
> There's no requirement that there be only one io_service per process,
> nor that it be dealt with in the main (original) thread.
>
> My current design actually has a bit of an explosion of io_service
> instances: for each client, I end up with one input + thread and one
> output + thread, to make sure that the input processing / data
> generation doesn't overwhelm the output bandwidth (and hence cause
> memory exhuastion by generating data faster than we can send it).
>
>> Wouldn't mind if there were a couple of ideas recommending what I
>> might explore next.
>
> Hopefully obvious, but the main reason for seg faults is when threads
> expect an object to exist somewhere, but a different thread has
> already destroyed ("destructed") the object.
>
>> boost::thread runner_([&server_]() {
>> server_->start_server();
>> });
>> runner_.start_thread();
>
> Boost.thread starts automatically, I thought?
>
> For that matter, where does "start_thread" even exist? It's not in
> the current documentation...
>
> Ah, looks like it was removed about a year ago. Fair enough. Just
> use creation as start.

Okay.

>> while (!timer_.has_elapsed_query_wait(wait_timeout_,
>> elapsed_milliseconds_)) {
>> //...
>> }
>>
>> runner_.interrupt();
>> runner_.join();
>
> Given that thread interruption is a bit dicey, you might consider
> doing the timeout work in the thread / io_service itself. That way,
> the controller only needs to launch the thread, then join it.

Not sure what you mean by dicey. If by dicey you mean that accept()
blocks altogether, interrupt requests and all, then, yes, I'll agree
dicey.

Obviously, this won't work either, because if a client never connects
(which is a possibility when testing), then that can't hang up the
rest of the app.

Can you be more specific? In the io_service itself?

>> boost::system::error_code ec_;
>> a_.accept((*s_), ec_);
>> if (!ec_) return;
>
> Since you're catching exceptions *anyway*, don't bother with error
> codes unless you're detecting specific values (as you do for eof
> elsewhere).

I am, I believe, checking for bytes, are bytes available, this sort of
thing. Instead of receive blocking when there is no data, which is one
plausible use case.

As soon as I schedule an async_accept, I get a segmentation fault.

I don't know the inner workings of the io_service that well, but I
suspect that may be because I have created the server outside the
running thread.

Something you mentioned earlier though, which is starting to click
with me: io_service might be the thing I want to run and/or have time
out, and just bypass needing to do anything with threads.

It's a little bit different than what I expected and/or am used to.

>> void server2::session(socket_pointer s) {
>
>> while (true) {
>> {
>
> No reason for this extra scope, either.
>
>> std::vector<byte> buffer_;
>> size_t length_ = s_.read_some(boost::asio::buffer(buffer_), ec_);
>
> This is fishy. buffer_ has length 0, yet you're trying to read into
> it. Maybe add a "buffer_.resize( 1024 )" (or whatever sounds good to
> you).
>
> Good luck,
> t.
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net