Re[4]: asio готовится к принятию в стандарт?
От: niXman Ниоткуда https://github.com/niXman
Дата: 17.05.15 09:39
Оценка: +2 -5
Здравствуйте, fdn721, Вы писали:

F>А как? Ну вот к примеру стандартная ситуация:

F>
F>class MyClient
F>{
F>protected:
F>  tcp::socket m_socket;

F>public:
F>  bool Open()
F>  {
F>    ....
F>    m_socket.async_connect( m_endpoint, boost::bind( &MyClient::HandleConnect, this, _1 ) );
F>  }

F>  void Close()
F>  {
F>    m_socket.close()
F>  }

F>protected:
F>  void HandleConnect(  const boost::system::error_code& err )
F>  {
F>    //do somthing
F>  }

F>}

F>int main()
F>{
F>  ...
F>  MyClient *client = new MyClient();
F>  client->Open();
F>  client->Close();   //<<---- Тут ASIO запланирует вызов HandleConnect со значением error::operation_aborted.
F>  delete client;     //<<---- А сам вызов HandleConnect может быть уже после удаления client.
F>  ...
F>}
F>

F>Как с этим бороться без кучи костылей???
нет смысла говорить о "высоком", видя в хэлоуворде такое:

MyClient *client = new MyClient();
...
delete client;

поверьте, не в asio ваши проблемы
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 17.05.2015 12:19 niXman . Предыдущая версия . Еще …
Отредактировано 17.05.2015 9:40 niXman . Предыдущая версия .
Re[6]: asio готовится к принятию в стандарт?
От: niXman Ниоткуда https://github.com/niXman
Дата: 18.05.15 12:43
Оценка: -3 :))
Здравствуйте, flаt, Вы писали:

F>Можно подумать, от auto client = std::make_shared<MyClient>() что-то изменится в понимании примера.

ну, значит автору того хэлоуворда есть еще куда учиться бессмысленности...
надеюсь, в следующий раз, в хэлоуворд, он обязательно впишет ваш, бессмысленный для хэлоуворда, пример
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 18.05.2015 12:45 niXman . Предыдущая версия .
Re[7]: asio готовится к принятию в стандарт?
От: smeeld  
Дата: 23.04.15 13:11
Оценка: +2 :)
Здравствуйте, PM, Вы писали:


PM>Проблемы будут с asio, как и с какой-то другой библиотекой асинхронности, потому что асинхронность это сложно. И часто асинхронность используют еще и многопоточной среде, что только добавляет сложности.


В asio сама реализация асинхронности занимает наименьшую часть кода. И это самая простая часть кода. Всё остальное-это
врайперы, сводящие воедино кучи интерфейсов и куч ОСей.

PM>Может быть я ошибаюсь, и есть альтернативы Asio? Я немного работал с libuv, там тоже не все просто.


Если нет требоавания кроссплатформа, то писать на нативном API ОС, будет проще, чем разбираться с
фантазиями создателей asio.
Re[14]: asio готовится к принятию в стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 27.04.15 12:36
Оценка: +3
Здравствуйте, uzhas, Вы писали:

J>>Далее, зачем обязательно убивать сокет явно? Достаточно хранить его в любом умном указателе и передавать явно в континуацию. Тогда при закрытии сокета в континуацию придет operation_aborted — ты в результате просто не поставишь в очередь очередную континуацию (которая держала бы сокет на плаву), и сокет мирно помрет сам вместе с указателем.


U>работа с внешними ресурсами часто требует полного и явного контроля. если говорить о сокетах, то иногда нужно явно освободить порт.


socket.close() его _уже_ освободил, не?

U>полагаться на shared_ptr я бы не стал из-за непредсказуемости кол-ва владельцев (более точно из-за непредсказуемости момента уничтожения захваченного объекта)


порт уже будет освобожден при помощи socket.close(). shared_ptr просто удалит неактивный объект, когда asio дернет все продолжения, которые с ним связаны (c operation_aborted).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[16]: asio готовится к принятию в стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 27.04.15 17:36
Оценка: +3
Здравствуйте, fdn721, Вы писали:

F>Здравствуйте, jazzer, Вы писали:


J>>Здравствуйте, uzhas, Вы писали:


U>>>полагаться на shared_ptr я бы не стал из-за непредсказуемости кол-ва владельцев (более точно из-за непредсказуемости момента уничтожения захваченного объекта)


J>>порт уже будет освобожден при помощи socket.close(). shared_ptr просто удалит неактивный объект, когда asio дернет все продолжения, которые с ним связаны (c operation_aborted).


F>Всё маленько сложнее, хэндлеры(продолжения) могут в момент socket.close() исполняться.


asio тут ни при чем вообще.
У тебя просто некорректная многопоточная работа с разделяемым объектом, не защищенным мьютексом.
Эта проблема у тебя будет абсолютно везде, хоть с asio, хоть с рукопашными pthreads.
Нельзя допускать, что в одном потоке ты пишешь в сокет (или куда угодно еще, хоть в memory mapped segment), а в другом — его (сокет/сегмент) убиваешь, и это может происходить одновременно.
В принципе нельзя. Надо обязательно защищать, никаких тут других вариантов нет, это же классические гонки по граблям.

F>Если после socket.close() сразу разрывать связь MyClient с остальной программой (освободить m_dataProcessor), то мы нарвёмся на очень нехорошую ситуацию.

А зачем ее сразу разрывать, если это просто указатель? Просто дождаться нормальной смерти MyClient никак нельзя?

F>Мы всё равно можем получить вызов m_dataProcessor->ProcessData(...) когда считаем что соединение уже завершено.

Это называется data race. Asio тут ни при чем.

F>PS В общем после попытки использовать asio осталось стойкое впечатление что я что-то делаю не так. Но ни где не написано как надо делать. Всё больше советов от теоретиков, типа используй shared_from_this и всё получится.


Я, как практик asio, имею в своем MyClient конечный автомат (обычный enum). И когда мни приходит в голову прибить клиента и его многочисленные сокеты/таймеры (например, по таймеру "что-то давно не было хартбита с той стороны") — я перевожу его состояние в состояние "сворачиваемся". После чего продолжения отработают и перезапущены не будут, и объект мирно умрет.

ЗЫ readed — такого слова нет. Read — неправильный глагол, у него все три формы совпадают.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 23.04.15 05:34
Оценка: +1 -1
Да зачем оно там нужно в таком виде???

Когда они сделают возможность закрыть сокет, и дождаться завершения всех асинхронных хэндлеров по нему без тонны костылей и/или без остановки io_service? Это же просто ужас какой-то!
Re[4]: трололо
От: о_О
Дата: 23.04.15 06:10
Оценка: +1 -1
Здравствуйте, fdn721, Вы писали:

F>Как с этим бороться без кучи костылей???


ну, ты эта, не массив сортируешь...
асинхронные вещи требуют асинхронного управления. вся asio — костыль, но твой пример хреновый аргумент против.
Re[5]: трололо
От: fdn721  
Дата: 23.04.15 06:28
Оценка: +2
Здравствуйте, о_О, Вы писали:

о_О>ну, ты эта, не массив сортируешь...

о_О>асинхронные вещи требуют асинхронного управления. вся asio — костыль, но твой пример хреновый аргумент против.

С асинхронными вещами трудно работать. Иногда нужно просто выполнить несколько несложных операций, а они навязывают тебе целую идеологию и архитектуру.

Мне вот непонятно почему не предусмотреть простой механизм, который бы позволил дождаться завершения всех асинхронных операций по сокету. Это бы решило кучу проблем.

И вообще во всей документации и примерах по ASIO старательно умалчивают про корректное завершение работы.
У них там бесконечный цикл в main, а все данные обрабатываются прямо в классе клиента. А как только ты начинаешь взаимодействовать из клиент с остальными частями программы, опять возникает куча проблем.

Я не против того что так устроена сторонняя библиотека ASIO, но тащить непродуманное решение в стандарт я бы не стал.
Re[6]: asio готовится к принятию в стандарт?
От: smeeld  
Дата: 23.04.15 10:46
Оценка: -2
Здравствуйте, fdn721, Вы писали:

F>И что мне делать с названием библиотеки? Ну асинхронная она и что теперь сокеты не закрывать и объекты не удалять?


Нужное поведение достаточно просто внедрить своим патчем. Будет asio вести себя как нужно
отдельно взятому индивиду. На то он и опенсорс.
Re[8]: asio готовится к принятию в стандарт?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 23.04.15 23:56
Оценка: +2
Здравствуйте, smeeld, Вы писали:

S>Если нет требоавания кроссплатформа, то писать на нативном API ОС, будет проще, чем разбираться с

S>фантазиями создателей asio.

Только в результате получится еще одно ASIO реализующее фантазии другого автора, только более глючное, так как в отладку вложить сопоставимые ресурсы будет трудно. Не нравится ASIO – возьми другую библиотеку по вкусу, благо альтернатив очень много.
Re[5]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 18.05.15 03:56
Оценка: +1 -1
Здравствуйте, niXman, Вы писали:

X>нет смысла говорить о "высоком", видя в хэлоуворде такое:

X>

X>MyClient *client = new MyClient();
X>...
X>delete client;

X>поверьте, не в asio ваши проблемы

Ещё один теоретик.
Re[5]: asio готовится к принятию в стандарт?
От: flаt  
Дата: 18.05.15 10:29
Оценка: +1 -1
Здравствуйте, niXman, Вы писали:

F>> MyClient *client = new MyClient();

Можно подумать, от auto client = std::make_shared<MyClient>() что-то изменится в понимании примера.
asio готовится к принятию в стандарт?
От: niXman Ниоткуда https://github.com/niXman
Дата: 22.04.15 21:16
Оценка: 6 (1)
глянул ньюсы по последней небустовой версии, и обрадовался.



просто оставлю это тут.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 22.04.2015 21:21 niXman . Предыдущая версия . Еще …
Отредактировано 22.04.2015 21:19 niXman . Предыдущая версия .
Re[4]: asio готовится к принятию в стандарт?
От: ArtDenis Россия  
Дата: 23.04.15 07:29
Оценка: +1
Здравствуйте, fdn721, Вы писали:

F>Как с этим бороться без кучи костылей???


Мда... Тяжёлый случай. Название библиотеки не пробовал расшифровывать?
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: asio готовится к принятию в стандарт?
От: PM  
Дата: 23.04.15 10:43
Оценка: +1
Здравствуйте, fdn721, Вы писали:

F>А как? Ну вот к примеру стандартная ситуация:

[здесь был код]
F>Как с этим бороться без кучи костылей???

Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.

class MyClient : public boost::enable_shared_from_this<MyClient>
{
protected:
  tcp::socket m_socket;

public:
  bool Open()
  {
    ....
    m_socket.async_connect( m_endpoint, boost::bind( &MyClient::HandleConnect, shared_from_this(), _1 ) );
  }

  void Close()
  {
    m_socket.close()
  }

protected:
  void HandleConnect(  const boost::system::error_code& err )
  {
    //do somthing
  }

}

int main()
{
  ...
  boost::shared_ptr<MyClient> client = boost::make_shared<MyClient>();
  client->Open();
  client->Close();   //<<---- Тут ASIO запланирует вызов HandleConnect со значением error::operation_aborted.
//  delete client;     //<<---- не нужно, объект будет удален, когда на него не останется ссылок
  ...
}
Re[5]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 23.04.15 12:25
Оценка: -1
Здравствуйте, PM, Вы писали:

PM>Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.


Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.

ЗЫ По началу кажется что ASIO это очень мощное решение, а по факты всегда всё сводится к одному подходу. Шаг влево, шаг в право и у тебя куча проблем.
Re[6]: asio готовится к принятию в стандарт?
От: PM  
Дата: 23.04.15 12:55
Оценка: +1
Здравствуйте, fdn721, Вы писали:

F>Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.


F>ЗЫ По началу кажется что ASIO это очень мощное решение, а по факты всегда всё сводится к одному подходу. Шаг влево, шаг в право и у тебя куча проблем.


В вашем примере кода была обычная проблема со временем жизни объекта, которая решается обычным способом

Проблемы будут с asio, как и с какой-то другой библиотекой асинхронности, потому что асинхронность это сложно. И часто асинхронность используют еще и многопоточной среде, что только добавляет сложности.

Может быть я ошибаюсь, и есть альтернативы Asio? Я немного работал с libuv, там тоже не все просто.
Re[6]: asio готовится к принятию в стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 24.04.15 05:24
Оценка: -1
Здравствуйте, fdn721, Вы писали:

F>Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.


проверить в этой "куче асинхронных операций" error::operation_aborted религия не позволяет?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 24.04.15 08:26
Оценка: :)
Здравствуйте, jazzer, Вы писали:


J>Что значит "handler ещё выполняется во время close"? Что один поток зовет close, пока в другом работает handler? Ну так защищать надо мьютексами, чтоб не было такого


Вот это я и называю костылями. Нужна насовать мютексов/флагов во все handler-ы только ради того, чтобы корректно закрыть соединение.
Re[10]: asio готовится к принятию в стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 24.04.15 08:36
Оценка: +1
Здравствуйте, fdn721, Вы писали:

J>>Что значит "handler ещё выполняется во время close"? Что один поток зовет close, пока в другом работает handler? Ну так защищать надо мьютексами, чтоб не было такого


F>Вот это я и называю костылями. Нужна насовать мютексов/флагов во все handler-ы только ради того, чтобы корректно закрыть соединение.


Эти "костыли" нужны всегда, когда у тебя объекты шарятся между потоками, и asio тут вообще ни при чем.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: asio готовится к принятию в стандарт?
От: smeeld  
Дата: 25.04.15 07:19
Оценка: +1
Здравствуйте, PM, Вы писали:

PM>Вы только что описали ручное управление жизнью объектов, для которого и предназначен shared_ptr. И про удаление в случае ошибки нужно не забыть в каждом асинхронном обработчике


Где только таких учат и откуда они вообще берутся? А голову они нигде не забывают? Этот хронические
жабисты пусть забывают, любой C++ ник должен уметь вручную управлять объектами, несмотря на обилие
ptr-ов, ибо пригодится, и вообще, ручное управление памятью есть одно из ключевых возможностей в C++,
доставшихся в наследство из Cи.

PM>Почему-то вы исходите из предпослыки, что обработчики asio выполняются в одном потоке. На самом деле можно (и нужно в Windows) запускать несколько потоков обработки на одном io_service. В этом случае, в вашем примере кода в serv::start() потребуется mutex, защищающий conn_mas, как и реализации функции del_conn()


А можно вообще без mutex-ов, и вообще без каких либо локов, просто распареллелив данные между потоками.
Re[5]: asio готовится к принятию в стандарт?
От: Vain Россия google.ru
Дата: 26.04.15 11:00
Оценка: +1
Здравствуйте, PM, Вы писали:

PM>int main()

PM>{
PM> ...
PM> boost::shared_ptr<MyClient> client = boost::make_shared<MyClient>();
PM> client->Open();
PM> client->Close(); //<<---- Тут ASIO запланирует вызов HandleConnect со значением error::operation_aborted.
PM>// delete client; //<<---- не нужно, объект будет удален, когда на него не останется ссылок
PM> ...
PM>}
Так тут точно такая же проблема: client будет удалён также после выхода из блока, что не гарантирует что все хендлеры завершаться до него.
Вообще сам подсчёт ссылок не решает проблем с удалением данных после завершения выполнения кода связанного с этими данными. А иногда делает даже хуже, т.к. ты не знаешь в какой момент объект разрушиться, нет вообще гарантий, что при написании какого-то кусочка кода объект в этот момент не будет жить или наоборот будет разрушен. Каждый раз при добавлении подобного кода приходится проходить мысленно по всей модели взаимодействий кода и данных. А это задалбывает.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 18.05.15 15:02
Оценка: -1
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, flаt, Вы писали:


F>>Можно подумать, от auto client = std::make_shared<MyClient>() что-то изменится в понимании примера.

X>ну, значит автору того хэлоуворда есть еще куда учиться бессмысленности...
X>надеюсь, в следующий раз, в хэлоуворд, он обязательно впишет ваш, бессмысленный для хэлоуворда, пример

У тебя уже два абсолютно бессмысленных поста. Не надоело сотрясать воздух? Ест что написать по темы? Нет? Давай, до свиданья!
Re[9]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 19.05.15 05:53
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>ага. все, кто с тобой не согласны, или говорят то, что тебе не удобно — ведьмы и еретики, и их всех нужно сжечь. можешь сколько угодно выдавать желаемое за действительное, и сколь угодно лгать себе, но повторюсь: если ты ТАКОЕ пишешь в хэлоуворде — твои проблемы не в asio, от слова совсем.


1) Что такое хэлоуворд знаешь? Что-то я сомневаюсь. Это не хэлоуворд. Это пример, который я на коленке написал за 30 секунд.

2) У меня всего один вопрос, как закрыть сокет и дождаться освобождения всех ресурсов самым простым способом?
Что-то ни кто на него не так и не ответил. Ты похоже тоже не можешь на него ответить.

3) С кем я не согласился? Я всего лишь указал ряд проблем в том или ином подходе.

И наконец прилетаешь ты, и начинаешь мне рассказывать про опасность простых указателей, и про то что я ни чего не понимаю. Гениально!
Re[2]: asio готовится к принятию в стандарт?
От: ArtDenis Россия  
Дата: 23.04.15 05:37
Оценка:
Здравствуйте, fdn721, Вы писали:

F>Да зачем оно там нужно в таком виде???


F>Когда они сделают возможность закрыть сокет, и дождаться завершения всех асинхронных хэндлеров по нему без тонны костылей и/или без остановки io_service? Это же просто ужас какой-то!


А в чём проблема-то это сейчас сделать?
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 23.04.15 05:55
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>А в чём проблема-то это сейчас сделать?


А как? Ну вот к примеру стандартная ситуация:
class MyClient
{
protected:
  tcp::socket m_socket;

public:
  bool Open()
  {
    ....
    m_socket.async_connect( m_endpoint, boost::bind( &MyClient::HandleConnect, this, _1 ) );
  }

  void Close()
  {
    m_socket.close()
  }

protected:
  void HandleConnect(  const boost::system::error_code& err )
  {
    //do somthing
  }

}

int main()
{
  ...
  MyClient *client = new MyClient();
  client->Open();
  client->Close();   //<<---- Тут ASIO запланирует вызов HandleConnect со значением error::operation_aborted.
  delete client;     //<<---- А сам вызов HandleConnect может быть уже после удаления client.
  ...
}

Как с этим бороться без кучи костылей???
Re: asio готовится к принятию в стандарт?
От: flаt  
Дата: 23.04.15 07:04
Оценка:
Здравствуйте, niXman, Вы писали:

X>Implemented changes to substantially reflect the Networking Library Proposal (N4370).

Boost.Asio была предложена ещё в 2006 году в рамках TR2.
Re[6]: трололо
От: flаt  
Дата: 23.04.15 07:19
Оценка:
Здравствуйте, fdn721, Вы писали:

F>С асинхронными вещами трудно работать. Иногда нужно просто выполнить несколько несложных операций, а они навязывают тебе целую идеологию и архитектуру.

Именно поэтому сейчас продвигают resumable functions (async/await) как помощь в решении проблем с асинхронностью.
Re[6]: трололо
От: ArtDenis Россия  
Дата: 23.04.15 08:13
Оценка:
Здравствуйте, fdn721, Вы писали:

F>С асинхронными вещами трудно работать.


Ну так не работай. Работай в блокирующем режиме. Библиотека позволяет.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[5]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 23.04.15 09:10
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Мда... Тяжёлый случай. Название библиотеки не пробовал расшифровывать?


И что мне делать с названием библиотеки? Ну асинхронная она и что теперь сокеты не закрывать и объекты не удалять?
Re[6]: asio готовится к принятию в стандарт?
От: ArtDenis Россия  
Дата: 23.04.15 09:37
Оценка:
Здравствуйте, fdn721, Вы писали:

F>И что мне делать с названием библиотеки? Ну асинхронная она и что теперь сокеты не закрывать и объекты не удалять?


Ну так и работай в асинхронном стиле, если ты её используешь в асинхронном стиле. Ваш КО.
В чём проблема-то?
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: asio готовится к принятию в стандарт?
От: flаt  
Дата: 23.04.15 17:00
Оценка:
Здравствуйте, fdn721, Вы писали:

F>А как? Ну вот к примеру стандартная ситуация:

F>Как с этим бороться без кучи костылей???
Кстати, можно использовать синхронные варианты
Re[7]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 24.04.15 06:35
Оценка:
Здравствуйте, jazzer, Вы писали:

J>проверить в этой "куче асинхронных операций" error::operation_aborted религия не позволяет?


Все такие умные, а если handler ещё выполняется во время close? Close ни чего не ждёт.
Re[5]: asio готовится к принятию в стандарт?
От: ArtDenis Россия  
Дата: 24.04.15 07:07
Оценка:
Здравствуйте, flаt, Вы писали:

F>Кстати, можно использовать синхронные варианты


Я уже предлагал
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[8]: asio готовится к принятию в стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 24.04.15 07:12
Оценка:
Здравствуйте, fdn721, Вы писали:

F>Здравствуйте, jazzer, Вы писали:


J>>проверить в этой "куче асинхронных операций" error::operation_aborted религия не позволяет?


F>Все такие умные, а если handler ещё выполняется во время close? Close ни чего не ждёт.


Что значит "handler ещё выполняется во время close"? Что один поток зовет close, пока в другом работает handler? Ну так защищать надо мьютексами, чтоб не было такого
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: asio готовится к принятию в стандарт?
От: smeeld  
Дата: 24.04.15 07:32
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Только в результате получится еще одно ASIO реализующее фантазии другого автора, только более глючное, так как в отладку вложить сопоставимые ресурсы будет трудно. Не нравится ASIO – возьми другую библиотеку по вкусу, благо альтернатив очень много.


Во первых, asio не глючное, во вторых, не факт что глючным будет своя реализация, и в третьих,
в своей реализации будут не отвлечённые фантазии, а воплощение именно того, что нужно в конкретном
приложении и ничего лишнего.
Отредактировано 24.04.2015 8:28 smeeld . Предыдущая версия .
Re[11]: asio готовится к принятию в стандарт?
От: uzhas Ниоткуда  
Дата: 24.04.15 09:02
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Эти "костыли" нужны всегда, когда у тебя объекты шарятся между потоками, и asio тут вообще ни при чем.


претензия fdn721 состоит в том, что asio не предлагает средств для уменьшения сложности написания программ с асинхр вводом\выводом (более конкретно, проблема завершения приложения и отмены асинхр операций, отслеживание времени жизни объектов). как следствие имеем хрупкий код, нестабильность, падения
именно asio должен был что-то предложить.
как вариант, сигнатура функции асинхронных операций должна не только принимать континуацию, но и выдавать хендл для управления запущенной операцией. это практикуется в том же C#:
https://msdn.microsoft.com/en-us/library/dd321424(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx

пример:
template<typename ConnectHandler>
Task<void> async_connect(
    const endpoint_type & peer_endpoint,
    ConnectHandler handler);
Отредактировано 24.04.2015 9:21 uzhas . Предыдущая версия .
Re[12]: asio готовится к принятию в стандарт?
От: Evgeny.Panasyuk Россия  
Дата: 24.04.15 09:23
Оценка:
Здравствуйте, uzhas, Вы писали:

J>>Эти "костыли" нужны всегда, когда у тебя объекты шарятся между потоками, и asio тут вообще ни при чем.

U>претензия ТС состоит в том, что asio не предлагает средств для уменьшения сложности написания программ с асинхр вводом\выводом

Asio предлагает и stackless coroutines и stackful.
Отредактировано 24.04.2015 9:24 Evgeny.Panasyuk . Предыдущая версия .
Re[13]: asio готовится к принятию в стандарт?
От: uzhas Ниоткуда  
Дата: 24.04.15 09:41
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Asio предлагает ... coroutines


покажи плиз как их применить в примере http://rsdn.ru/forum/cpp.applied/6025182.1
Автор: fdn721
Дата: 23.04.15

а пример вот о чем:
1) создается объект
2) запускается асинхр операция по коннекту (или чтению данных)
3) уничтожается объект явным образом
Re[5]: asio готовится к принятию в стандарт?
От: The Passenger Голландия  
Дата: 24.04.15 10:43
Оценка:
Здравствуйте, PM, Вы писали:

PM>Здравствуйте, fdn721, Вы писали:


F>>А как? Ну вот к примеру стандартная ситуация:

PM>[здесь был код]
F>>Как с этим бороться без кучи костылей???

PM>Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.


а как в Read при таком подходе избавиться от зацикливания ?
( я в принципе знаю — но это тоже костыль )

во вторых — например на таймерах можно дождаться их завершения — не понимаю какая проблема сделать тоже самое на сокетах ... можно конечно свой condition воткнуть, но почему бы
не делать это силами библиотеки?
Весь мир — Кремль, а люди в нем — агенты
Re[6]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 24.04.15 11:05
Оценка:
Здравствуйте, The Passenger, Вы писали:

PM>>Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.


Это не подход, а оторванные от жизни примеры. Объект(будем называть его соединение) само по себе не живет(если это не эхо сервер), оно всё равно связано с остальной программой. Так вот реализовать эту связь с соединением, у которого какое-то произвольное время жизни, проблематично. Кроме того этим соединением часто приходится управлять из вне(т.е. им кто-то владеет, посылает данные, получает ответы). Ну вот к примеру надо переустановить соединение, как это сделать корректно при таком подходе? Всё обрастёт кучей мютексов и week_ptr-ов. Если у тебя есть хорошее решение — поделись, я тебе буду благодарен.
Re[7]: asio готовится к принятию в стандарт?
От: smeeld  
Дата: 24.04.15 12:26
Оценка:
Здравствуйте, fdn721, Вы писали:

F>Это не подход, а оторванные от жизни примеры. Объект(будем называть его соединение) само по себе не живет(если это не эхо сервер), оно всё равно связано с остальной программой. Так вот реализовать эту связь с соединением, у которого какое-то произвольное время жизни, проблематично. Кроме того этим соединением часто приходится управлять из вне(т.е. им кто-то владеет, посылает данные, получает ответы). Ну вот к примеру надо переустановить соединение, как это сделать корректно при таком подходе? Всё обрастёт кучей мютексов и week_ptr-ов.


Для каждого соединения создаётся объект с отдельным asio сокетом как полем объекта. Объект,
при создании, помещается в дерево, список или хеш. Асинхронные обработчики будут являться методами
этих объектов. Этот объект уничтожается если в асинхронный хендлер передаётся сообщение об ошибке,
или закрытии соединения, после чего объект сам себя уничтожает, в своём же методе, то есть в асинхронном
обработчике. Всё операции и хендлеры обработки результатов их выполнения, исполняются в одном потоке io_service.
Поток io_service сам выбирает asio сокет для которого нужно вызвать хендлер, а тот уже определяет "свой" объект,
так как в asio функции хендлер "передаётся с объектом"
void serv::start(){
  conn* p=0;
  if(p=new_conn(this))
   if(conn_mas.insert(p).second) 
    accept.async_accept(p->sock, boost::bind(&conn::start, p, _1));
   else del_conn(p);
 };

void conn::start(const boost::system::error_code& er)
 {
 server->start();
 if(!er)
 sock.async_read_some(boost::asio::buffer(read_buf, SOME_SIZE), boost::bind(&conn::write_handler, this, _1, _2));
 else del_conn(this);
 };

и совершает действия с его полями, составляя состояние того или иного соединения.
При уничтожении всех соединений, можно пройтись по всему дереву/списку с его очищением. Если одного потока io_service
оказыватся мало, можно создать их любое количество, с отдельным деревом соединений на каждый.
Re[8]: asio готовится к принятию в стандарт?
От: PM  
Дата: 25.04.15 05:15
Оценка:
Здравствуйте, smeeld, Вы писали:


S>Для каждого соединения создаётся объект с отдельным asio сокетом как полем объекта. Объект,

S>при создании, помещается в дерево, список или хеш. Асинхронные обработчики будут являться методами
S>этих объектов. Этот объект уничтожается если в асинхронный хендлер передаётся сообщение об ошибке,
S>или закрытии соединения, после чего объект сам себя уничтожает, в своём же методе, то есть в асинхронном
S>обработчике. Всё операции и хендлеры обработки результатов их выполнения, исполняются в одном потоке io_service.
S>Поток io_service сам выбирает asio сокет для которого нужно вызвать хендлер, а тот уже определяет "свой" объект,
S>так как в asio функции хендлер "передаётся с объектом"

Вы только что описали ручное управление жизнью объектов, для которого и предназначен shared_ptr. И про удаление в случае ошибки нужно не забыть в каждом асинхронном обработчике

Почему-то вы исходите из предпослыки, что обработчики asio выполняются в одном потоке. На самом деле можно (и нужно в Windows) запускать несколько потоков обработки на одном io_service. В этом случае, в вашем примере кода в serv::start() потребуется mutex, защищающий conn_mas, как и реализации функции del_conn()

Ну то есть в итоге придем к тому, что fdn721 назвал костылями.
Re[6]: asio готовится к принятию в стандарт?
От: PM  
Дата: 25.04.15 05:22
Оценка:
Здравствуйте, The Passenger, Вы писали:

PM>>Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.


TP>а как в Read при таком подходе избавиться от зацикливания ?

TP>( я в принципе знаю — но это тоже костыль )

Зацикливания чего, ссылок на объекты или обработчиков? Непонятный вопрос.

TP>во вторых — например на таймерах можно дождаться их завершения — не понимаю какая проблема сделать тоже самое на сокетах ... можно конечно свой condition воткнуть, но почему бы

TP>не делать это силами библиотеки?

Я не автор, но могу предположить, потому что это непросто сделать кроссплатформенно.
Re[7]: asio готовится к принятию в стандарт?
От: ArtDenis Россия  
Дата: 25.04.15 07:18
Оценка:
Здравствуйте, fdn721, Вы писали:

F>Это не подход, а оторванные от жизни примеры. Объект(будем называть его соединение) само по себе не живет(если это не эхо сервер), оно всё равно связано с остальной программой. Так вот реализовать эту связь с соединением, у которого какое-то произвольное время жизни, проблематично.


Вот у меня, например, совсем не эхо сервер. И соединение прекрасно живёт себе в виде умного указателя в недрах io_service + у меня в списке. После того, как я для соединения делаю close и удаляю из своего списка соединений, как только asio завершит для него все асинхронные операции, связанные с закрытием сокета, оно прекрасно удаляется из недр io_service, после чего умный указатель вызывает деструктор объекта соединения. Это замечательно работает, избавляя меня от необходимости ручного управления памятью.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[10]: asio готовится к принятию в стандарт?
От: PM  
Дата: 25.04.15 19:58
Оценка:
Здравствуйте, smeeld, Вы писали:

PM>>Вы только что описали ручное управление жизнью объектов, для которого и предназначен shared_ptr. И про удаление в случае ошибки нужно не забыть в каждом асинхронном обработчике


S>Где только таких учат и откуда они вообще берутся? А голову они нигде не забывают? Этот хронические

S>жабисты пусть забывают, любой C++ ник должен уметь вручную управлять объектами, несмотря на обилие
S>ptr-ов, ибо пригодится, и вообще, ручное управление памятью есть одно из ключевых возможностей в C++,
S>доставшихся в наследство из Cи.

Жизнь таких учит, что в С++ коде внезапно бывают исключения, что люди ошибаются, что код меняется. Должен уметь != должен делать. Если вам незнакомо RAII и нравится писать в стиле С, так и пишите на С, пользуйтесь на здоровье goto cleanup.

PM>>Почему-то вы исходите из предпослыки, что обработчики asio выполняются в одном потоке. На самом деле можно (и нужно в Windows) запускать несколько потоков обработки на одном io_service. В этом случае, в вашем примере кода в serv::start() потребуется mutex, защищающий conn_mas, как и реализации функции del_conn()


S>А можно вообще без mutex-ов, и вообще без каких либо локов, просто распареллелив данные между потоками.


Можно многое, но если будет использоваться пул потоков для обработчиков асинхронных операций, без блокировок в каком-либо виде не обойтись.

Хотя, дискутировать с вами не собираюсь, тема была не про это. Ваша позиция ясна из предыдущих сообщений. Надеюсь, мне не придется с вами работать в одной команде, либо поддерживать ваш код.
Re[6]: asio готовится к принятию в стандарт?
От: PM  
Дата: 25.04.15 20:05
Оценка:
Здравствуйте, fdn721, Вы писали:

F>Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.


F>ЗЫ По началу кажется что ASIO это очень мощное решение, а по факты всегда всё сводится к одному подходу. Шаг влево, шаг в право и у тебя куча проблем.


Несколько лет назад смотрел код libtorrent, там использовалась asio.

Можно еще посмотреть на https://github.com/mabrarov/asio_samples
Re[12]: asio готовится к принятию в стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 27.04.15 03:24
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, jazzer, Вы писали:


J>>Эти "костыли" нужны всегда, когда у тебя объекты шарятся между потоками, и asio тут вообще ни при чем.


U>претензия fdn721 состоит в том, что asio не предлагает средств для уменьшения сложности написания программ с асинхр вводом\выводом (более конкретно, проблема завершения приложения и отмены асинхр операций, отслеживание времени жизни объектов). как следствие имеем хрупкий код, нестабильность, падения

U>именно asio должен был что-то предложить.
U>как вариант, сигнатура функции асинхронных операций должна не только принимать континуацию, но и выдавать хендл для управления запущенной операцией.

Ну так тогда придется где-то хранить эти хэндлы, так что тот же гемор, вид сбоку
У fdn721 же добавление континуации и удаление сокета разнесены в коде, я так предполагаю (иначе можно было бы просто континуацию не создавать, если мы знаем, что тут же сокет прибьем)


Далее, зачем обязательно убивать сокет явно? Достаточно хранить его в любом умном указателе и передавать явно в континуацию. Тогда при закрытии сокета в континуацию придет operation_aborted — ты в результате просто не поставишь в очередь очередную континуацию (которая держала бы сокет на плаву), и сокет мирно помрет сам вместе с указателем.


ЗЫ Есть какой-нть нормальный перевод для continuation? Калька — это уродство какое-то "Продолжение" тоже плохо выглядит, так как имеет самостоятельный смысл. "Функция/процедура продолжения"?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[13]: asio готовится к принятию в стандарт?
От: uzhas Ниоткуда  
Дата: 27.04.15 09:11
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ну так тогда придется где-то хранить эти хэндлы, так что тот же гемор, вид сбоку


это не вид сбоку, это доп. рычаг, который позволяет в другой манере работать с теми же вещами. и может гораздо проще решить проблему fdn721
это все равно, что отождествить все языки программирования "они же все эквивалентны машине Тьюринга". хотя разные языки одну и ту же задачу могут решать по-разному в плане перформанса, простоты кода\сопровождения и тд.

J>Далее, зачем обязательно убивать сокет явно? Достаточно хранить его в любом умном указателе и передавать явно в континуацию. Тогда при закрытии сокета в континуацию придет operation_aborted — ты в результате просто не поставишь в очередь очередную континуацию (которая держала бы сокет на плаву), и сокет мирно помрет сам вместе с указателем.


работа с внешними ресурсами часто требует полного и явного контроля. если говорить о сокетах, то иногда нужно явно освободить порт. полагаться на shared_ptr я бы не стал из-за непредсказуемости кол-ва владельцев (более точно из-за непредсказуемости момента уничтожения захваченного объекта)

J>ЗЫ Есть какой-нть нормальный перевод для continuation? Калька — это уродство какое-то "Продолжение" тоже плохо выглядит, так как имеет самостоятельный смысл. "Функция/процедура продолжения"?


обычно переводят, как "продолжение".
у слова "функция" и "процедура" тоже много значений в русском языке, главное — привыкнуть
но в данном контексте все же это слово не следует употреблять, у него несколько другое значение : http://en.wikipedia.org/wiki/Continuation
в данном случае мы все же работаем с async method handler, то есть с обработчиками асинхронных операций, которые в свою очередь часто являются замыканиями ( http://en.wikipedia.org/wiki/Closure_(computer_programming) ) имхо
Re[14]: asio готовится к принятию в стандарт?
От: Evgeny.Panasyuk Россия  
Дата: 27.04.15 09:18
Оценка:
Здравствуйте, uzhas, Вы писали:

EP>>Asio предлагает ... coroutines

U>покажи плиз как их применить в примере http://rsdn.ru/forum/cpp.applied/6025182.1
Автор: fdn721
Дата: 23.04.15

U>а пример вот о чем:
U>1) создается объект
U>2) запускается асинхр операция по коннекту (или чтению данных)
U>3) уничтожается объект явным образом

При использовании stackless coroutines так же как и в обычном случае — при входе в автомат делается проверка error_code. И если там ошибка — то передача продолжения в следующую асинхронную операцию не происходит, текущее продолжение тихо завершается и либо самоудаляется, либо уменьшает ref count.

В случае stackful — при ошибке происходит либо выброс исключения (стэк раскручивается и корутина завершается), либо же можно получить тот же error_code и самому решить что делать дальше.

Оба примера есть в Asio (1, 2), там разве что не хватает вызова close.
Re[14]: asio готовится к принятию в стандарт?
От: Evgeny.Panasyuk Россия  
Дата: 27.04.15 09:49
Оценка:
Здравствуйте, uzhas, Вы писали:

J>>Ну так тогда придется где-то хранить эти хэндлы, так что тот же гемор, вид сбоку

U>это не вид сбоку, это доп. рычаг, который позволяет в другой манере работать с теми же вещами. и может гораздо проще решить проблему fdn721
U>это все равно, что отождествить все языки программирования "они же все эквивалентны машине Тьюринга". хотя разные языки одну и ту же задачу могут решать по-разному в плане перформанса, простоты кода\сопровождения и тд.

Покажи как бы выглядел код использующий Asio с этими хэндлерами.

J>>Далее, зачем обязательно убивать сокет явно? Достаточно хранить его в любом умном указателе и передавать явно в континуацию. Тогда при закрытии сокета в континуацию придет operation_aborted — ты в результате просто не поставишь в очередь очередную континуацию (которая держала бы сокет на плаву), и сокет мирно помрет сам вместе с указателем.

U>работа с внешними ресурсами часто требует полного и явного контроля.

Часто нужен не явный контроль, а всего лишь prompt finalization, который прекрасно обеспечивается RAII.

U>если говорить о сокетах, то иногда нужно явно освободить порт. полагаться на shared_ptr я бы не стал из-за непредсказуемости кол-ва владельцев


Не надо раздавать shared_ptr кому попало.

U>(более точно из-за непредсказуемости момента уничтожения захваченного объекта)


Если в какой-то точке программы (в другом потоке?) нужно дождаться момента разрушения какого-то объекта, то необходимо делать блокирующее ожидание.

U>обычно переводят, как "продолжение".

U>у слова "функция" и "процедура" тоже много значений в русском языке, главное — привыкнуть
U>но в данном контексте все же это слово не следует употреблять, у него несколько другое значение : http://en.wikipedia.org/wiki/Continuation

Ты ссылаешься на то continuation, которое подразумевается в call-with-current-continuation. Есть же второе значение, которое в подразумевается в continuation-passing style.
Тем не менее эти значения очень близки. Я бы даже сказал что это не разные значения continuation, а само понятие continuation более общее, которое и покрывает эти оба конкретных случая — CPS или call/cc.

U>в данном случае мы все же работаем с async method handler, то есть с обработчиками асинхронных операций, которые в свою очередь часто являются замыканиями ( http://en.wikipedia.org/wiki/Closure_(computer_programming) ) имхо


Продолжения тоже часто являются замыканиями.
Я считаю что вполне уместно называть хэндлер асихнронной операции продолжением — это уже устоявшаяся практика.
Re[15]: asio готовится к принятию в стандарт?
От: uzhas Ниоткуда  
Дата: 27.04.15 11:07
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Покажи как бы выглядел код использующий Asio с этими хэндлерами.


например, так:
class MyClient
{
protected:
  tcp::socket m_socket;
  task<void> m_ConnectTask;

public:
  bool Open()
  {
    ....
    m_ConnectTask = m_socket.async_connect( m_endpoint, boost::bind( &MyClient::HandleConnect, this, _1 ) );
  }

  void Close()
  {
    m_socket.close();
    m_ConnectTask.wait(); //blocks if there is incomplete async op, non blocking if there is no associated async op
  }

protected:
  void HandleConnect(  const boost::system::error_code& err )
  {
    //do something
  }

}

int main()
{
  ...
  MyClient *client = new MyClient();
  client->Open();
  client->Close();
  delete client;
  ...
}


EP>Часто нужен не явный контроль, а всего лишь prompt finalization, который прекрасно обеспечивается RAII.

я не вижу, как RAII поможет в примере выше. более того, socket.close — это не RAII, однако без него было бы еще сложнее =)

EP>Не надо раздавать shared_ptr кому попало.

дисциплину тяжело крыть автотестами, нужны более понятные средства, помогающие писать надежный софт

EP>Если в какой-то точке программы (в другом потоке?) нужно дождаться момента разрушения какого-то объекта, то необходимо делать блокирующее ожидание.


EP>Ты ссылаешься на то continuation, которое подразумевается в call-with-current-continuation. Есть же второе значение, которое в подразумевается в continuation-passing style.

в CPS тоже речь не о колбеке, а о целой ветке исполнения

EP>Продолжения тоже часто являются замыканиями.

согласен

EP>Я считаю что вполне уместно называть хэндлер асихнронной операции продолжением — это уже устоявшаяся практика.

а я считаю наоборот, это плохая практика, также как и писать "длинна", хоть это и распространенная практика
Re[15]: asio готовится к принятию в стандарт?
От: fdn721  
Дата: 27.04.15 17:18
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, uzhas, Вы писали:


U>>полагаться на shared_ptr я бы не стал из-за непредсказуемости кол-ва владельцев (более точно из-за непредсказуемости момента уничтожения захваченного объекта)


J>порт уже будет освобожден при помощи socket.close(). shared_ptr просто удалит неактивный объект, когда asio дернет все продолжения, которые с ним связаны (c operation_aborted).


Всё маленько сложнее, хэндлеры(продолжения) могут в момент socket.close() исполняться. Если после socket.close() сразу разрывать связь MyClient с остальной программой (освободить m_dataProcessor), то мы нарвёмся на очень нехорошую ситуацию.

class MyClient : public boost::enable_shared_from_this<MyClient>
{
protected:
  tcp::socket m_socket;
  IDataProcessor* m_dataProcessor;

public:
  bool Open( IDataProcessor* processor )
  {
    ....
    m_socket.async_connect( m_endpoint, boost::bind( &MyClient::HandleConnect, shared_from_this(), _1 ) );
  }

  void Close()
  {
    m_socket.close()
    m_dataProcessor->ProcessDisconnect();
    m_processor = nullptr;
  }

protected:
  void HandleConnect(  const boost::system::error_code& err )
  {
    ...
    m_dataProcessor->ProcessConnect();
    m_socket.async_receive( m_buffert, boost::bind( &MyClient::HandleRead, shared_from_this(), _1 ) );
  }

  void HandleRead( const boost::system::error_code& err, size_t readed )
  {
    if( err == error::operation_aborted )    
    return;    

    ...    //Когда мы были где-то тут, был вызван Close() -> m_socket.close()

    m_dataProcessor->ProcessData( m_buffer, readed );

    ...

    m_socket.async_receive( m_buffert, boost::bind( &MyClient::HandleRead, shared_from_this(), _1 ) );
  }

}


Можно использовать week_ptr<IDataProcessor>, но это спасёт только от нулевого указателя. Мы всё равно можем получить вызов m_dataProcessor->ProcessData(...) когда считаем что соединение уже завершено. Это неприятный побочный эффект, который надо учитывать в IDataProcessor.

Можно в каждый хэндлер и Close добавить приметив синхронизации, и проверять состояние сокета. Но это костыль.

Можно руками следить за текущим состоянием всех хэндлеров и ждать в Close их завершения, и это тоже костыль.

PS В общем после попытки использовать asio осталось стойкое впечатление что я что-то делаю не так. Но ни где не написано как надо делать. Всё больше советов от теоретиков, типа используй shared_from_this и всё получится.
Re[17]: asio готовится к принятию в стандарт?
От: uzhas Ниоткуда  
Дата: 28.04.15 06:07
Оценка:
J>ЗЫ readed — такого слова нет.

Это устоявшаяся практика
Re[16]: asio готовится к принятию в стандарт?
От: PM  
Дата: 28.04.15 07:06
Оценка:
Здравствуйте, fdn721, Вы писали:

...


F>Можно использовать week_ptr<IDataProcessor>, но это спасёт только от нулевого указателя. Мы всё равно можем получить вызов m_dataProcessor->ProcessData(...) когда считаем что соединение уже завершено. Это неприятный побочный эффект, который надо учитывать в IDataProcessor.


F>Можно в каждый хэндлер и Close добавить приметив синхронизации, и проверять состояние сокета. Но это костыль.


F>Можно руками следить за текущим состоянием всех хэндлеров и ждать в Close их завершения, и это тоже костыль.


F>PS В общем после попытки использовать asio осталось стойкое впечатление что я что-то делаю не так. Но ни где не написано как надо делать. Всё больше советов от теоретиков, типа используй shared_from_this и всё получится.


Как уже написал jazzer, обычно в активных объектах такого типа можно использовать некий конечный автомат, так что в состоянии `closed connection` обработка данных не будет выполняться.

Но, в принципе, волшебства не будет — в многопоточной программе данные придется защищать. Как вариант, можно поставить на исполнение функцию закрытия сокета в очередь к другим обработчикам с помощью `io_service::post([](){ m_socket.close(); })`

Еще желательно помнить, что если асинхронные обработчики выполняются в пуле потоков, то для соблюдения последовательности вызовов обработчиков нужно использовать io_service::strand.

Подход с coroutines, упомянутый Evgeny.Panasyuk выглядит проще, но это тоже нужно разбираться и читать документацию. Я на практике еще не использовал coroutines.
Re[6]: asio готовится к принятию в стандарт?
От: PM  
Дата: 28.04.15 07:30
Оценка:
Здравствуйте, Vain, Вы писали:

PM>>int main()

PM>>{
PM>> ...
PM>> boost::shared_ptr<MyClient> client = boost::make_shared<MyClient>();
PM>> client->Open();
PM>> client->Close(); //<<---- Тут ASIO запланирует вызов HandleConnect со значением error::operation_aborted.
PM>>// delete client; //<<---- не нужно, объект будет удален, когда на него не останется ссылок
PM>> ...
PM>>}
V>Так тут точно такая же проблема: client будет удалён также после выхода из блока, что не гарантирует что все хендлеры завершаться до него.

Вообще то этот пример код не является минимально полным рабочим, ни у fdn721, ни у меня. Обычно таки в программе есть что-то типа io_thread.join() которое гарантирует завершение обработчиков asio до выхода из какого-то блока.

V>Вообще сам подсчёт ссылок не решает проблем с удалением данных после завершения выполнения кода связанного с этими данными. А иногда делает даже хуже, т.к. ты не знаешь в какой момент объект разрушиться, нет вообще гарантий, что при написании какого-то кусочка кода объект в этот момент не будет жить или наоборот будет разрушен. Каждый раз при добавлении подобного кода приходится проходить мысленно по всей модели взаимодействий кода и данных. А это задалбывает.


Серебряной пули нет Я вообще не часто использую shared_ptr, но для откладывания на потом решения, когда удалить объект он полезен. Мысленно ходить далеко не надо — объект не разрушится, пока на него есть ссылки. Для слабых ссылок есть weak_ptr, для которого проверяется результат lock()

Проверяли же 15 лет назад сырые указатели на NULL и не жаловались. А некоторые до сих пор агитируют за ручное управление памятью.
Re[16]: asio готовится к принятию в стандарт?
От: Evgeny.Panasyuk Россия  
Дата: 28.04.15 14:09
Оценка:
Здравствуйте, uzhas, Вы писали:

EP>>Покажи как бы выглядел код использующий Asio с этими хэндлерами.

U>например, так:
U>
U>    m_socket.close();
U>    m_ConnectTask.wait(); //blocks if there is incomplete async op, non blocking if there is no associated async op
U>


А каков механизм блокирования? Там могут быть разные случаи:

1. Всё происходит в одном потоке, в котором запущен io_service.
Заблокировать поток нельзя, так как тогда не выполнится хэндлер — получаем deadlock. Нужно внутри wait'а крутить io_service, например через run_one. Но, если соединений очень много, и каждое будет делать такой wait, можем запросто получить stackoverflow — конечно можем увеличить адресное пространство стэка, но как-то получается не айс.

2. В одном потоке запущен io_service, а ждать нужно в другом, в котором он не запущен. Здесь достаточно future.

3. Есть два потока, в каждом из которых крутится свой io_service, либо один и тот же. Полностью блокировать плохо, нужно крутить run_one — что опять же может привести к stackoverflow.

EP>>Часто нужен не явный контроль, а всего лишь prompt finalization, который прекрасно обеспечивается RAII.

U>я не вижу, как RAII поможет в примере выше. более того, socket.close — это не RAII, однако без него было бы еще сложнее =)

socket.close это действительно не RAII. RAII помогает освободить ресурсы в этих хэндлерах после этого явного close, причём как prompt finalization.

EP>>Не надо раздавать shared_ptr кому попало.

U>дисциплину тяжело крыть автотестами,

Можно ограничивать доступ через private.

U>нужны более понятные средства, помогающие писать надежный софт


Проблема с ресурсами в контексте асинхронных обработчиков есть и в GC языках — там это один из основных use-case'ов для утечек, только помимо этого ещё и отсутствует нормальное prompt finalization.

EP>>Если в какой-то точке программы (в другом потоке?) нужно дождаться момента разрушения какого-то объекта, то необходимо делать блокирующее ожидание.

EP>>Ты ссылаешься на то continuation, которое подразумевается в call-with-current-continuation. Есть же второе значение, которое в подразумевается в continuation-passing style.
U>в CPS тоже речь не о колбеке, а о целой ветке исполнения

Так при использовании Asio тоже приходится делать целую ветку исполнения.

EP>>Я считаю что вполне уместно называть хэндлер асихнронной операции продолжением — это уже устоявшаяся практика.

U>а я считаю наоборот, это плохая практика, также как и писать "длинна", хоть это и распространенная практика

У тебя может есть ссылка на значимый первоисточник, в котором чётко написано что такое handler, а что такое continuation?
Если такого каноничного источника нет, то и приходится опираться на распространенную практику
Отредактировано 28.04.2015 14:11 Evgeny.Panasyuk . Предыдущая версия .
Re[8]: asio готовится к принятию в стандарт?
От: niXman Ниоткуда https://github.com/niXman
Дата: 18.05.15 15:14
Оценка:
ага. все, кто с тобой не согласны, или говорят то, что тебе не удобно — ведьмы и еретики, и их всех нужно сжечь. можешь сколько угодно выдавать желаемое за действительное, и сколь угодно лгать себе, но повторюсь: если ты ТАКОЕ пишешь в хэлоуворде — твои проблемы не в asio, от слова совсем.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.