Невозможно правильно создать приложение камеры Raspberry Pi как дочерний процесс из приложения C++

Я пишу приложение на Raspberry Pi/Raspbian на C++. Я создаю именованный канал (FIFO) с mkfifo() затем я начинаю распиять, чтобы захватить изображение с моей камеры. Для памяти raspiyuv - это приложение командной строки Raspberry Pi, которое берет неподвижные изображения и сохраняет их в виде файла YUV.

Я использую g++ 6.3 и Boost 1.64 с -std= C++ 17. FIFO, который я создаю, является правильным в том смысле, что я могу использовать его из командной строки. Работает как положено.

Баг в том, что приложение, распияв I spawn, возвращается сразу с кодом выхода 0.

Мой код:

void myFunction()
{
    // Create the FIFO here with mkfifo(); // Works fine...
    boost::filesystem::path lExecPath = 
        boost::process::search_path( "raspiyuv" );  // returns correct path
    boost::process::child lProcess( lExecPath, "-w 2592 -h 1944 -o - -t 0 -y -s >> /var/tmp/myfifo" );
    int lPID = lProcess.id();   // Seems to be correct
    int lExitCode = lProcess.exit_code();  // Returns immediately with 0
}

Команда $ raspiyuv -w 2592 -h 1944 -o - -t 0 -y -s правильно, когда я ввожу его прямо в командную строку. Кроме того, перенаправление на FIFO работает правильно. -w 2592 -h 1944 дать размер захваченного изображения, -o - означает вывод изображения на стандартный вывод, -t 0 значит ждать вечно, -y означает сохранить только канал Y и -s означает ждать, пока SIGUSR1 запустит захват изображения.

Когда я вызываю его из командной строки, приложение бездействует, пока я не отправлю SIGUSR1, затем оно захватывает изображение и передает его в FIFO, а затем возвращает бездействие. Все в порядке.

Когда я порождаю это, создавая boost::process::child объект, он сразу возвращается.

Любая идея, чтобы исправить это и позволить boost::process::child остаться в живых до тех пор, пока мое приложение (родительский процесс) живо, а я не отправляю SIGKILL и т. д.?

Спасибо за вашу помощь!

1 ответ

boost::process::child работает асинхронно с основным процессом. Если вы хотите синхронного поведения, то вы должны либо позвонить lProcess.wait() или запустить этот распиюв синхронными средствами вроде использования boost::process::system,

РЕДАКТИРОВАТЬ: Если вы хотите, чтобы другой процесс был асинхронным (как, по-видимому, указывают ваши изменения и комментарии), то, что вы действительно пытаетесь сделать, становится неясным для меня:

Баг в том, что приложение, распияв I spawn, возвращается сразу с кодом выхода 0.

Какая ошибка? По документам boost::process::child это именно то , что ожидается:

  1. int exit_code () const; Получите код выхода. Возвращаемое значение не имеет никакого значения, если дочерний элемент не ожидался или был прерван.

Ваш код нигде не ожидает завершения дочернего процесса и поэтому получает код выхода, как описано в документации.

Другие вопросы по тегам