приложения fork и execve, некоторые из них в порядке с condition_variable, а другие - одновременно - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь выполнить несколько приложений с помощью fork () и execve (). и некоторые из них имеют зависимость друг от друга. Так, например, я хочу, чтобы он выполнял A, B, C одновременно и заставлял его ждать, пока B не перейдет в состояние «Выполнение», прежде чем выполнить C, когда сценарий подобен приведенному ниже.

applications
A
B-C   (C depends on B)
D

в самый первый раз. Я придумал очень примитивное решение, как показано ниже. Разверните и выполните приложение и дождитесь, пока его состояние не изменится на работающее. (приложение имеет начальное состояние, и все готово, оно отправляет сообщение о том, что оно находится в рабочем состоянии в state_mgr)

// app_starter.cpp
CreateAppProcess(...) {
   ...
   child = fork();
   ...
   if (child == 0) {
      execve(name, argv, argc);
      ...
   }
   ...
}


StartApplication(AppInstance& app) {
...
    CreateAppProcess(app->name, app->argv, app->argc);
...
}

Используйте функцию «StartApplication ()» таким образом.

//app_starter.cpp

// 1. declare AppInstance array.
AppInstance app_array[10];  
// 2. set AppInstances in the array.
...
// 3. start apps
for (int i = 0 ; i < 10; i++) {
   StartApplication(app_array[i]);
}

// 4. wait until "execve"d app is on Running state.
for (int i = 0; i < 1000000000; i++) 
{
    return_value = app_ins.GetAppState(app->name);
    if(return_value == State::Running) break;
}

Приведенное выше решение имеет три проблемы.

  1. оно может выполнять только одно приложение за раз.
  2. должно подождать, пока предыдущее приложение находится в состоянии «Работает», даже если это не является зависимостью.
  3. для l oop продолжайте потреблять ресурсы, выполняющие GetAppState () несколько раз.

Поэтому я пытаюсь решить проблемы одну за другой, но я застрял на самое первое решение для 3. - условие_ переменное.

// app_instance.cpp
std::condition_variable g_app_cv;
std::mutex g_app_cv_mtx;
...
ReceiveAppStateMsg() {
    while(_quit) {
        ret_ = mq_receive(rcv_handler, buffer, size_, 0);
        ...
        if (msg_rcvd == State::Running) {
            ...
            g_app_cv.notify_one();
        }
    }
}

//app_starter.cpp
extern std::condition_variable g_app_cv;
extern std::mutex g_app_cv_mtx;

// 1. declare AppInstance array.
AppInstance app_array[10];  
// 2. set AppInstances in the array.
...
// 3. start apps  - change for loop to condition_variable.
for (int i = 0 ; i < 10; i++) {
   StartApplication(app_array[i]);
}

// 4. wait until "execve"d app is on Running state.
{
    std::unique_lock<std::mutex> lk(g_app_cv_mtx);
    g_app_cv.wait_for(lk, std::chrono::milliseconds(1000));
}

В заключение мне нужно кое-что узнать о ...

  1. Как использовать condition_variable для нескольких файлов cpp.

  2. Правильный путь fork () и exe c () с std :: condition_variable.

    • хочу знать, что мое решение является правильным.
  3. Как выполнить fork () и exe c () одновременно или с небольшой задержкой.

execution order timeline I want
start --- |end
--------------
 A----|
  B----|C----|
   D----|
--------------

Спасибо, что прочитали этот длинный вопрос.

1 Ответ

0 голосов
/ 10 марта 2020

Вам необходимо распределить мьютекс и переменную условия в общей области памяти между процессами. Вам также нужно установить атрибут вашего мьютекса и cond vars равным PTHREAD_PROCESS_SHARED

Как поделиться памятью: ссылка

Однако для целей, аналогичных вашей, я бы предпочитаю писать небольшой модуль жизненного цикла процесса (полностью построенный поверх IP C с использованием доменных сокетов). Вы можете разделить жизненный цикл вашего процесса на: INIT, RUNNING, ALIVE, STOPPED, DEAD (основываясь на том, что вы хотите сделать, я просто даю вам подсказки). Как только ваш процесс достигнет стадии своего жизненного цикла, вы можете опубликовать sh событие, уведомляющее об этом. Другой процесс может просто сидеть и ждать, пока это состояние будет реализовано в процессе сотрудничества. Простой механизм биения сердца может определить, является ли другой процесс ЖИВЫМ или мертвым. О других этапах можно уведомить, опубликовав через IP C (предпочтительные доменные сокеты)

...