Как использовать boost::async_system?

Я новичок в бустинге, а также в многопоточности и запуске приложений с использованием библиотек. Для моей желаемой функциональности коллега порекомендовал мне использовать библиотеку boost::process.

Но документации к этой части boost совершенно недостаточно, поэтому по документации я не смог определить, какая функция лучше всего подходит для моей задачи. Поэтому я начал пробовать там несколько функций, но не обладает всеми нужными свойствами.

Однако есть один, который я не могу понять, как правильно использовать. Я даже не могу его скомпилировать, не говоря уже о том, чтобы запустить. И функция boost::process::async_system. Я не смог нигде найти в Интернете пошаговое руководство о том, как использовать эту функцию и что означают и что делают отдельные компоненты.

Может ли кто-нибудь подробно объяснить мне отдельные аргументы и аргументы шаблона функции? Или дать ссылку на подробный мануал?


person TStancek    schedule 28.01.2019    source источник
comment
Вы видели этот boost.org/doc/ libs/master/doc/html/boost/process/?   -  person Mayur    schedule 28.01.2019
comment
Да, но я действительно не знаю, как это должно дать мне какое-то понимание...   -  person TStancek    schedule 28.01.2019


Ответы (2)


Мне нравятся примеры здесь: https://theboostcppplibraries.com/boost.thread-futures-and-promises

Например, посмотрите пример 44.16, там наглядно показано, как использовать асинхронность:

#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <iostream>

int accumulate()
{
  int sum = 0;
  for (int i = 0; i < 5; ++i)
    sum += i;
  return sum;
}

int main()
{
  boost::future<int> f = boost::async(accumulate);
  std::cout << f.get() << '\n';
}

Ожидание происходит в методе get, а не раньше. Вы также можете использовать механизм без ожидания.

Что касается компиляции, вам нужно сначала собрать boost. Сборка подробно описана здесь: https://www.boost.org/doc/libs/1_62_0/more/getting_started/windows.html

Большинство частей библиотеки работают только с заголовками. Для asio необходимо собрать двоичные библиотеки (также объясненные в ссылке). В вашем проекте (например, в проектах Visual Studio, проекте xcode или просто в некоторых файлах make) вам необходимо установить заголовки включения и библиотеки для его использования. Ссылка выше помогает и в этом.

person IceFire    schedule 28.01.2019
comment
Ага, спасибо за информацию, но у меня буст билд, проблема в ошибке, что у меня в голове не укладывается, сначала подумал, что это из-за некорректного использования функции, но начинает казаться ошибкой со стороны разработчика, хотя и маловероятно, но все же возможно. Ошибка include/boost-1_66/boost/process/async_system.hpp:70:22: error: 'h' здесь нельзя использовать как функцию: h(boost::system::error_code(ec.value()) , boost::system::system_category()), -1);. Что бы я ни делал, я получаю эту ошибку (версия boost 1.66). - person TStancek; 28.01.2019

Я просто наращиваю Boost.Process, но пример кода, который у меня есть, может быть здесь полезен.

boost::process:async_system () принимает 3 параметра: boost:: asio::io_context, функцию обработчика выхода и команду, которую вы хотите запустить (так же, как system(), и это может быть как одна строка, так и несколько аргументов).

После его вызова вы используете объект io_context из вызывающего потока для управления и мониторинга асинхронной задачи — я использую метод run_one(), который «запускает цикл обработки событий объекта io_context для выполнения не более одного обработчика», но вы также можете использовать другие методы для запуска в течение продолжительного времени и т. д.

Вот мой рабочий код:

#include <boost/process.hpp>
#include <iostream>

using namespace boost;

namespace {
    // declare exit handler function
    void _exitHandler(boost::system::error_code err, int rc) {
        std::cout << "DEBUG async exit error code: " 
                  << err << " rc: " << rc <<std::endl;
    }
}

int main() {
    // create the io_context
    asio::io_context ioctx;

    // call async_system
    process::async_system(ioctx, _exitHandler, "ls /usr/local/bin");

    std::cout << "just called 'ls /usr/local/bin', async" << std::endl;
    int breakout = 0; // safety for weirdness
    do {
        std::cout << " - checking to see if it stopped..." << std::endl;
        if (ioctx.stopped()) {
            std::cout << " * it stopped!" << std::endl;
            break;
        } else {
            std::cout << " + calling io_context.run_one()..." << std::endl;
            ioctx.run_one();
        }
        ++breakout;
    } while (breakout < 1000);

    return 0;
}

Единственное, чего не хватает в моем примере, так это того, как использовать boost::asio::async_result для захвата результата. Образцы, которые я видел (в том числе и здесь, на slashdot), по-прежнему не имеют для меня особого смысла, но, надеюсь, они будут полезны. .

Вот вывод вышеизложенного в моей системе:

just called 'ls /usr/local/bin', async
 - checking to see if it stopped...
 + calling io_context.run_one()...
 - checking to see if it stopped...
 + calling io_context.run_one()...
VBoxAutostart       easy_install        pybot
VBoxBalloonCtrl     easy_install-2.7    pyi-archive_viewer
   ((omitted - a bunch more files from the ls -l command))
DEBUG async exit error code: system:0 rc: 0
 - checking to see if it stopped...
 * it stopped!
Program ended with exit code: 0
person Corbell    schedule 03.07.2019