Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Requirements on asynchronous operations

Boost , Boost.Asio , Reference

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

В Росте. Asio, асинхронная операция инициируется функцией, которая называется с префиксом<async_>. Эти функции называютсяинициирующими функциями..

Все инициирующие функции усиливаются. В качестве конечного параметра Asio берет объект функции, отвечающийтребованиям обработчика. Эти обработчики принимают в качестве своего первого параметра значение типа<consterror_code>.

Внедрение асинхронных операций в Boost. Asio может вызывать интерфейс прикладного программирования (API), предоставляемый операционной системой. Если такой вызов API операционной системы приводит к ошибке, обработчик будет вызываться с значением<consterror_code>lvalue, которое оценивается как истинное. В противном случае обработчик будет ссылаться на значение<consterror_code>lvalue, которое оценивается как ложное.

Если не указано иное, когда поведение асинхронной операции определяется как "как если бы", реализованное функциейPOSIX, обработчик будет вызываться со значением типа<error_code>, которое соответствует состоянию отказа, описанномуPOSIXдля этой функции, если таковое имеется. В противном случае обработчик будет вызываться с значением реализации<error_code>, которое отражает ошибку операционной системы.

Асинхронные операции не выходят из строя при условии ошибки, которая указывает на прерывание сигналомPOSIX<EINTR>. Асинхронные операции не потерпят неудачу при любом состоянии ошибки, связанном с неблокирующими операциямиPOSIX<EWOULDBLOCK>,<EAGAIN>или<EINPROGRESS>;Windows<WSAEWOULDBLOCK>или<WSAEINPROGRESS>.

Все асинхронные операции имеют ассоциированный<io_service>объект. Если инициирующая функция является функцией-членом, ассоциированная<io_service>является той, которая возвращается функцией-членом<get_io_service()>на том же объекте. Если инициирующая функция не является функцией-членом, ассоциированная<io_service>является той, которая возвращается<get_io_service()>функцией-членом первого аргумента к инициирующей функции.

Аргументы в отношении инициирующих функций будут рассматриваться следующим образом:

— Если параметр объявлен в качестве ссылки или по значению, программа не обязана гарантировать обоснованность аргумента после завершения инициирующей функции. Реализация может сделать копии аргумента, и все копии будут уничтожены не позднее, чем сразу после вызова обработчика.

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

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

— резьба выполняет любую функцию члена связанного<io_service>объекта.

— Нить выполняет деструктор связанного<io_service>объекта.

— Поток выполняет одну из функций<io_service>доступа к услугам<use_service>,<add_service>или<has_service>, где первым аргументом является связанный<io_service>объект.

— Нить выполняет любую функцию участника, конструктора или деструктора объекта класса, определенного в этом пункте, где функция участника объекта<get_io_service()>возвращает связанный<io_service>объект.

— Нить выполняет любую функцию, определенную в этом пункте, где любой аргумент функции имеет<get_io_service()>функцию члена, которая возвращает связанный<io_service>объект.

Объект<io_service>, связанный с асинхронной операцией, будет иметь незавершенную работу, как если бы путем поддержания существования одного или нескольких объектов класса<io_service::work>, построенных с использованием<io_service>, до тех пор, пока не будет вызван обработчик для асинхронной операции.

Когда асинхронная операция завершена, обработчик операции будет вызван, как если бы:

  1. Для этого необходимо установить<bch>, как описано ниже.
  2. Призыв<ios.post(bch)>, чтобы назначить обработчика для отложенного вызова, где<ios>связан<io_service>.

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

Обязательным обработчиком завершения является объект обработчика, который содержит копию обработчика, поставляемого пользователем, где обработчик, поставляемый пользователем, принимает один или несколько аргументов. Обязательный обработчик завершения не принимает никаких аргументов и содержит значения, которые должны быть переданы в качестве аргументов поставляемому пользователем обработчику. Обработчик завершения пересылает вызовы<asio_handler_allocate()>,<asio_handler_deallocate()>и<asio_handler_invoke()>к соответствующим функциям для обработчика, поставляемого пользователем. Обязательный обработчик завершения соответствует требованиям для обработчика завершения.

Например, связанный обработчик завершения для<ReadHandler>может быть реализован следующим образом:

template<class ReadHandler>
struct bound_read_handler
{
  bound_read_handler(ReadHandler handler, const error_code& ec, size_t s)
    : handler_(handler), ec_(ec), s_(s)
  {
  }
  void operator()()
  {
    handler_(ec_, s_);
  }
  ReadHandler handler_;
  const error_code ec_;
  const size_t s_;
};
template<class ReadHandler>
void* asio_handler_allocate(size_t size,
                            bound_read_handler<ReadHandler>* this_handler)
{
  using boost::asio::asio_handler_allocate;
  return asio_handler_allocate(size, &this_handler->handler_);
}
template<class ReadHandler>
void asio_handler_deallocate(void* pointer, std::size_t size,
                             bound_read_handler<ReadHandler>* this_handler)
{
  using boost::asio::asio_handler_deallocate;
  asio_handler_deallocate(pointer, size, &this_handler->handler_);
}
template<class F, class ReadHandler>
void asio_handler_invoke(const F& f,
                         bound_read_handler<ReadHandler>* this_handler)
{
  using boost::asio::asio_handler_invoke;
  asio_handler_invoke(f, &this_handler->handler_);
}

Если поток, который инициирует асинхронную операцию, заканчивается до вызова соответствующего обработчика, поведение определяется реализацией. В частности, наВерсии Windowsдо Vista отменяют незавершенные операции при выходе инициирующего потока.

Аргумент обработчика инициирующей функции определяет личность обработчика. То есть исходный аргумент обработчика и любые копии аргумента обработчика будут считаться эквивалентными. Если реализации необходимо выделить хранилище для асинхронной операции, то реализация будет выполнять<asio_handler_allocate(size,&h)>, где<size>- необходимый размер в байтах, а<h>- обработчик. Реализация будет выполнять<asio_handler_deallocate(p, size, &h)>, где<p>является указателем на хранилище, чтобы распределить хранилище до вызова обработчика через<asio_handler_invoke>. Несколько блоков хранения могут быть выделены для одной асинхронной операции.

Return type of an initiating function

По умолчанию функции инициации возвращаются<void>. Это всегда происходит, когда обработчиком является указатель функции, лямбда C++11 или объект функции, созданный<boost::bind>или<std::bind>.

Для других типов тип возврата может быть настроен с помощью двухэтапного процесса:

  1. Специализация шаблона<handler_type>, который используется для определения истинного типа обработчика на основе подписи обработчика асинхронной операции.
  2. Специализация шаблона<async_result>, который используется как для определения типа возврата, так и для извлечения значения возврата из обработчика.

Эти два шаблона были специально разработаны для поддержкистековых корутини класса C++11<std::future>.

В качестве примера рассмотрим, что происходит при включении поддержки<std::future>с помощью специального значения<boost::asio::use_future>, например:

std::future<std::size_t> length =
  my_socket.async_read_some(my_buffer, boost::asio::use_future);

Когда подпись обработчика имеет форму:

void handler(error_code ec, result_type result);

Инициирующая функция возвращает<std::future>шаблон<result_type>. В вышеприведенном примере<async_read_some>это<std::size_t>. Если асинхронная операция не удалась,<error_code>преобразуется в<system_error>исключение и передается обратно абоненту через будущее.

Если подпись обработчика имеет форму:

void handler(error_code ec);

Инициирующая функция возвращается<std::future<void>>.


PrevUpHomeNext

Статья Requirements on asynchronous operations раздела Boost.Asio Reference может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Reference ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:14:48/0.005748987197876/0