Возникли проблемы с ожиданием дочернего процесса с другим дочерним процессом в c ++ - PullRequest
1 голос
/ 30 марта 2019

У меня проблемы с управлением порядком вывода трех дочерних процессов в моем назначении c ++.

Таким образом, требование назначения - создать три дочерних процесса. А, В и С. Что я могу сделать это. Затем мне пришлось сделать несколько операций в трех дочерних процессах.

A: счетчик 12 шагов с печатью «A» и каждый раз в течение 1 секунды. B: напечатайте «B» после двух напечатанных «A» C: вывести «C» после прогона B 3 раза

Мне нужно, чтобы процессы выполнялись для выполнения задачи ...

sig_atomic_t sigusr1_count = 0;
bool bNeedDoWork = false;
bool cNeedDoWork = false;

void handlerForStep (int signal_number) //signal handler
{
 ++sigusr1_count;
}

void handlerForB (int signal_number) //signal handler
{
 bNeedDoWork = true;
}

void handlerForC (int signal_number) //signal handler
{
 cNeedDoWork = true;
}

int main() {
 using namespace std;
 pid_t childA_pid, childB_pid, childC_pid;

 /* Set up A handler operation*/
 struct sigaction sa; 
 memset (&sa, 0, sizeof (sa)); 
 sa.sa_handler = &handlerForStep; 
 sigaction (SIGUSR1, &sa, NULL); 

 childA_pid = fork();
 if (childA_pid == 0) {
   for (int i = 0; i < 12; i++) {
     system("echo A");
     kill(getppid(), SIGUSR1);
     sleep(1);
   }
   exit(0);

 } else {
   childB_pid = fork();
   if (childB_pid == 0) {

     /*Set up B handler operation*/
     /*...*/

     //sleep until handler B receive signal
     while (true) {
       sleep(1);
       if (bNeedDoWork) {
         bNeedDoWork = false;
         system("echo B");
       }
     }
     exit(0);

   } else {
     childC_pid = fork();
     if (childC_pid == 0) {

       /*Set up C handler operation*/
       /*...*/

       //sleep until handler C receive signal
       while (true) {
         sleep(1);
         if (cNeedDoWork) {
           cNeedDoWork = false;
           system("echo C");
         }
       }
       exit(0);

     } else {
       while (true) {
         sleep(1);
         if (sigusr1_count != 0 && sigusr1_count % 2 == 0) {
           kill(childB_pid, SIGUSR1);
         }
         if (sigusr1_count != 0 && sigusr1_count % 6 == 0) {
           kill(childC_pid, SIGUSR1);
         }
       }
     }
   }
 }
 return 0;
}


Немного длиннее. Но меня беспокоит, действительно ли это правильный способ генерирования процессов.

Я ожидал, что результатом будет "A A B A A B A A B C A A B A A B A A B C" Но в результате получается «A A B A A C B ........»

Который C напечатал до B напечатал. Даже некоторые буквы A, B, C перепутаны после этой последовательности.

Является ли этот метод подсчета для различения процесса B и процесса C:

if (sigusr1_count != 0 && sigusr1_count % 2 == 0) {
   kill(childB_pid, SIGUSR1);
}
if (sigusr1_count != 0 && sigusr1_count % 6 == 0) {
   kill(childC_pid, SIGUSR1);
}

правильный

Можно ли использовать wait(&status) для предотвращения срабатывания выхода C перед выводом B? Thankyou.

1 Ответ

0 голосов
/ 01 апреля 2019

Используйте pause(2), чтобы процессы ожидали сигнала неопределенно долго.Из-за гонки между этими двумя процессами все еще возможно напечатать C перед соответствующим B;Вы должны были бы связаться с процессом B, чтобы предотвратить это.И wait(2) не может помочь: только процесс A когда-либо завершается (пока, по-видимому, вы не используете ^C в терминале для уничтожения всей группы процессов).

...