наследовать дескрипторы канала и использовать их в дочернем процессе, используя boost :: process - PullRequest
1 голос
/ 20 сентября 2019

Я хотел создать async_pipe и передать их дочернему процессу.
Я прочитал официальные документы для boost :: process, и мне не удалось найти никаких примеров или объяснений того, что я пытаюсь сделать.делать.
(в нем есть пример кода, который выполняет подобные вещи, используя стандартное перенаправление ввода / вывода, которое не соответствует моим потребностям)
Я искал в Интернете и задавал вопросы, но все жеЕсть несколько вопросов, которые я хочу задать.Вот код:

//Parent Process Code
int main()
{
    namespace bp = boost::process;
    boost::asio::io_context ioc;

    bp::async_pipe send_pipe{ ioc };
    bp::async_pipe recv_pipe{ ioc };

    HANDLE send_src = send_pipe.native_source();
    HANDLE send_sink = send_pipe.native_sink();
    HANDLE recv_src = recv_pipe.native_source();
    HANDLE recv_sink = recv_pipe.native_sink();

    SetHandleInformation(send_src, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
    SetHandleInformation(send_sink, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
    SetHandleInformation(recv_src, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
    SetHandleInformation(recv_sink, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);

    const std::string cmd{ /* the child process program path */ };

    std::stringstream ss;
    ss << cmd << " " << send_sink << " " << send_src << " " << recv_sink << " " << recv_src;

    bp::child c{ ss.str(), bp::std_out = stdout };

    // read & write

    c.join();
    return 0;
}
//Child Process Code
int main(int argc, char* argv[])
{
    namespace bp = boost::process;

    std::stringstream ss;
    ss << argv[1] << " " << argv[2] << " " << argv[3] << " " << argv[4];

    HANDLE recv_src;
    HANDLE recv_sink;
    HANDLE send_src;
    HANDLE send_sink;

    ss >> recv_src >> recv_sink >> send_src >> send_sink;
    boost::asio::io_context ioc;

    bp::pipe temp_send_pipe{ send_src, send_sink };
    bp::pipe temp_recv_pipe{ recv_src, recv_sink };

    bp::async_pipe send_pipe{ ioc, temp_send_pipe };
    bp::async_pipe recv_pipe{ ioc, temp_recv_pipe };

    //I do these assigns because CloseHandle() for sink and source is called in basic_pipe's destructor 
    temp_send_pipe.assign_sink(INVALID_HANDLE_VALUE);
    temp_send_pipe.assign_source(INVALID_HANDLE_VALUE);
    temp_recv_pipe.assign_sink(INVALID_HANDLE_VALUE);
    temp_recv_pipe.assign_source(INVALID_HANDLE_VALUE);

    // read and write

    return 0;
}
  1. Я определенно считаю, что должен быть более изящный способ наследования дескрипторов канала.Я проверил код библиотеки и подумал, что ключом могут быть boost :: process :: child (Args &&), boost :: process :: args или pipe_out :: on_setup_t.Есть ли способ сделать это менее многословным?

  2. Когда я создал basic_pipe и наследовал дескрипторы, по крайней мере, он работал нормально.Но если я создаю async_pipe и наследую дескрипторы, это выдает ошибку со значением 87 (неверный параметр).Я подозреваю, что это происходит, когда унаследованные дескрипторы зарегистрированы в IOCP.Если мое предположение верно, почему это так?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...