TStancek
TStancek

Reputation: 318

How to use boost::async_system?

I am quite new to boost, as well as to multithreading and launching application using libraries. For my desired funcitonality, I was recommended by colleague to use boost::process library.

But the documentation to this part of boost is quite insufficient, so I could not determine which function suits my task best by documentation. I therefore started to try several functions there, but non has all the desired properties.

However there is one I cannot figure out, how to properly use. I cannot even compile it, let alone run it. And the function is boost::process::async_system. I could not find anywhere on internet some step-by-step guide on how to use this function and what individual components mean and do.

Could someone explain to me in detail the individual arguments and template arguments of the function ? Or provide a link to a detailed manual?

Upvotes: 4

Views: 1484

Answers (2)

Corbell
Corbell

Reputation: 1403

I'm just ramping up on Boost.Process but the sample code I have working might be helpful here.

boost::process:async_system() takes 3 parameters: a boost::asio::io_context object, an exit-handler function, and the command you want to run (just like system(), and it can be either a single line or more than one arg).

After it's invoked, you use the io_context object from the calling thread to manage and monitor the async task - I use the run_one() method which will "Run the io_context object's event processing loop to execute at most one handler" but you can also use other methods to run for a duration etc.

Here's my working code:

#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;
}

The only thing my example lacks is how to use boost::asio::async_result to capture the result - the samples I've see (including here on slashdot) still don't make much sense to me, but hopefully this much is helpful.

Here's the output of the above on my system:

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

Upvotes: 1

IceFire
IceFire

Reputation: 4137

I like the examples here: https://theboostcpplibraries.com/boost.thread-futures-and-promises

For example, look at example 44.16, they clearly show how to use async:

#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';
}

Waiting happens at the get method, not before. You might use a non-waiting mechanism, too.

As for compiling, you need to first build boost. Building is explained in detail here: https://www.boost.org/doc/libs/1_62_0/more/getting_started/windows.html

Most parts of the library work header-only. For asio, building the binary libraries (also explained in the link) is necessary. In your project (i.e. visual studio projects, xcode project or just some make files), you need to set include and library headers of boost to use it. The link above helps with this as well.

Upvotes: 0

Related Questions