1

How do I spawn multiple child processes that should run asynchronously? Do I use a vector of child processes? I'm afraid the code below doesn't do what I'm trying to accomplish. Any other suggestions for a different way to pass arguments to the child process is also welcome!

#include <iostream>
#include <string>
#include <sstream>
#include "boost/process.hpp"

int main()
{
    namespace bp = boost::process;

    std::string child_process_name = "child_process";

    std::cout << "main_process: before spawning" << std::endl;

    int num_processes = 5;
    for (int i = 0; i < num_processes; ++i)
    {
        std::cout << "main_process: spawning child " << i << std::endl;
        std::stringstream ss;
        ss << i;
        std::string is;
        ss >> is;
        bp::child c(child_process_name, std::vector<std::string> {is});
        c.join();
    }

    std::cout << "main_process: waiting for children" << std::endl;

    std::cout << "main_process: finished" << std::endl;

    return 0;
}
Bruno
  • 1,329
  • 2
  • 15
  • 35

2 Answers2

2

you are waiting for each process before starting the next one . instead you should spawn them all then wait for them outside the loop . here is the edited code :

#include <iostream>
#include <string>
#include <sstream>
#include "boost/process.hpp"

int main()
{
    namespace bp = boost::process;

    std::string child_process_name = "child_process";

    std::cout << "main_process: before spawning" << std::endl;

    constexpr int num_processes = 5;
    std::vector<bp::child> childs;
    childs.reserve(num_processes);

    for (int i = 0; i < num_processes; ++i)
    {
        std::cout << "main_process: spawning child " << i << std::endl;
        std::stringstream ss;
        ss << i;
        std::string is;
        ss >> is;
        childs.emplace_back(bp::child(child_process_name, std::vector<std::string> {is}));
    }

    std::cout << "main_process: waiting for children" << std::endl;
    
    for (auto& ch : childs)
        ch.join();
    
    std::cout << "main_process: finished" << std::endl;

    return 0;
} 
dev65
  • 1,440
  • 10
  • 25
  • 1
    Thanks! I was creating the vector as `std::vector children(num_processes);` and then assigning its elements as `children[i] = bp::child(child_process_name, std::vector {is});`, which was wrong. – Bruno Jun 26 '20 at 20:47
1

How about adding each process (ie. bp::child ) to a vector. Then in a separate loop that iterates over the vector, make your call to join(). Don't call join() within that loop you have there, or things will just run sequentially.