Использовать асинхронный вызов — это то же самое, что использовать синхронный вызов в потоке?

Я использую boost и хотел бы, чтобы это:

// --- some random function ---
boost::asio::io_service io;
boost::asio::ip::tcp::socket sock;
char b[256];
// connect and stuff here
boost::asio::async_read( sock,
    boost::asio::buffer(b, 256),
    boost::bind( &onRead, _1, _2)
    );

это то же самое

// --- some random function ---
boost::asio::io_service io;
boost::asio::ip::tcp::socket sock;
boost::thread *read_thread;
char b[256];
// connect and stuff here
read_thread = new boost::thread( 
    boost::bind( &boost::asio::io_service::run, &( io))
    );
io.post( &read, b, sock);


// --- read function
bool read( char b[], boost::asio::ip::tcp::socket sock){
    boost::asio::read( sock,
        boost::asio::buffer(b, 256),
        boost::bind( &onRead, _1, _2)
        );
}

Я просто хотел бы узнать, что происходит при асинхронном вызове и чем он отличается от синхронизации.

Отредактировано: мой главный вопрос: асинхронный вызов блокирует поток, связанный с io_service?

Отредактировано 2: это решило мои проблемы: http://www.ibm.com/developerworks/linux/library/l-async/?ca=dgr-lnxw02aUsingPOISIXAIOAPI


person lucastamoios    schedule 05.01.2013    source источник


Ответы (1)


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

Асинхронный вызов возвращается немедленно, но состояние работы неопределенно. Когда работа выполнена, зарегистрированная функция обратного вызова вызывается ioservice, и, поскольку вы запускаете эту службу в отдельном потоке, обратный вызов также выполняется в этом отдельном потоке.

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

person Kerrek SB    schedule 05.01.2013
comment
Но асинхронный вызов блокирует поток, связанный с референтом io_service? - person lucastamoios; 05.01.2013
comment
@lucastamoios: Нет, это не так. Сам ioservice реализует однопоточные асинхронные операции и цикл опроса. Только когда операция завершена, обратный вызов выполняется, не блокируя, но последовательно в потоке ioservice. - person Kerrek SB; 05.01.2013
comment
значит, в моем приложении есть невидимая нить??? Это было то, что я хотел знать. Спасибо. - person lucastamoios; 05.01.2013
comment
@lucastamoios: Нет, нить не невидима. Это прямо в вашем коде! Обратные вызовы запускаются из функции run() ioservice. - person Kerrek SB; 05.01.2013
comment
Я имею в виду, что есть какой-то поток, который обрабатывает асинхронную функцию, перед выполнением обратного вызова, например, в функции async_read, есть какое-то место, где обрабатывается чтение, поэтому, когда он завершается, обратный вызов, связанный в функции async_read, называется. Не так ли? - person lucastamoios; 05.01.2013
comment
@lucastamoios: чтение является асинхронным, поэтому функция async_read возвращается немедленно. Асинхронный ввод-вывод — это функция операционной системы, и пользовательский код не участвует в фактическом чтении байтов с устройства. Просто подумайте о цикле событий epoll (что и есть Boost.Asio). - person Kerrek SB; 05.01.2013
comment
Не могли бы вы показать мне какое-нибудь место, где я могу узнать больше об этом? Я имею в виду асинхронность как функцию ОС ... Спасибо всем этим ответам, это было действительно поучительно! (: - person lucastamoios; 05.01.2013