Почему ребенок этого класса не печатает? - PullRequest
0 голосов
/ 22 апреля 2019

Я создал класс, который должен обрабатывать подпроцесс, но когда я помещаю тестовую печать внутрь, ничего не происходит, может кто-нибудь сказать мне, почему?

Я пробовал разные типы печати и комбинации fflush, ноэто не решило проблему.

Вот мои файлы:

Kitchen.cpp

Kitchen::Kitchen()
{
    int wstatus;

    this->_pid = fork();
    if (this->_pid == 0) {
        std::cout << "child: " << this->_pid << std::endl;
    } else if (this->_pid == -1) {
        throw("No child");
    } else {
        std::cout << "parent: " << this->_pid << std::endl;
        waitpid(this->_pid, &wstatus, 1);
    }
}

Kitchen::~Kitchen()
{
    if (this->_pid > 0)
        kill(this->_pid, SIGKILL);
}

Kitchen.hpp

#pragma once

#include <signal.h>
#include <unistd.h>

class Kitchen {
    public:
        Kitchen();
        ~Kitchen();
    private:
        pid_t _pid;
};

Прием.cpp

int Reception::run_shell(void)
{
    this->_kitchens.push_back(Kitchen());
    return (0);
}

Reception..

Обратите внимание, что этот код работает вне класса.

Ответы [ 3 ]

1 голос
/ 22 апреля 2019

теперь лучше?

Да, лучше.


Я скопировал ваш код в Lubuntu 18.04 и, используя g ++ 7.3.0-27, получил его для компиляции.

Скопированный код моей системы воспроизвел вашу ошибку.

Хм.

Итак, я отправился на поиски и быстро нашел свой самый последний эксперимент с fork. Я не понимаю, почему это работает, а ваши нет, они выглядят достаточно похожими на меня.

Я использую переключатель вместо ваших вложенных if-then-else ... может быть, есть сбой во вложенных if-then-else? неправильная передача символа? Но я сомневаюсь в этом.


Итак ... по прагматическим соображениям я (минимально?) Изменил ваш код в соответствии с моим примером.

Возможно, вы можете задать лучший вопрос о том, почему это работает, а в вашей версии - нет.

Надеюсь, это поможет:

#include "../../bag/src/dtb_chrono.hh"
using  namespace std::chrono_literals;      // support suffixes like 100ms, 2s, 30us

#include <iostream>
using std::cout, std::cerr, std::flush, std::endl;

#include <string>
using std::string;

#include <thread>
using std::this_thread::sleep_for;

#include <vector>
using std::vector;

#include <cstring>
using std::strerror;

#include <unistd.h>   // fork
#include <sys/wait.h> // waitpid

#include <cassert>


class Kitchen
{
   pid_t child_pid;
   time_t pt0; // child  start time 0
   time_t ct0; // parent start time 0

public:
   Kitchen()
      {
         pt0 = time(0) + 2;
         ct0 = time(0) + 1;

         // On success, the PID of the child process is returned in the
         // parent, and 0 is returned in the child.
         //
         // On failure, -1 is returned in the parent, no child process is
         // created, and errno is set appropriately.

         child_pid = fork();

         switch (child_pid)
         {

         case -1: { errnoExit (errno, "\n  fork fail: ", -12); } break;

         case 0: // child
         {
            std::cout << "\n  i am child: " << child_pid << endl;
            ChildProcess();
         }
         break;

         default: // parent
         {
            std::cout << "\n  i am parent, child_pid: " << child_pid << flush;
            ParentProcess();
         }

         } // switch(child_pid)

      } // Kitchen

   ~Kitchen()
      {
         if (child_pid > 0)
         {   }; //  {  kill(child_pid, SIGKILL)};
      }

   void  ChildProcess(void)
      {
         int   i = 0;
         do {
            i += 1;
            cout  << "\n  child  " << i;
            std::this_thread::sleep_for(100ms);
            if (time(0) > ct0) break;
         }while (true);
         cout << "\n*** Child  complete ***" << '\n';
      }

   void  ParentProcess(void)
      {
         int   i = 0;
         do {
            i += 1;
            cout  << "\n  parent " << i ;
            std::this_thread::sleep_for(100ms);
            if (time(0) > pt0) break;
         }while (true);
         int wstatus;
         waitpid(child_pid, &wstatus, 1); // see output -
         // waitpid not effective because parent runs longer than child
         // but causes no harm ...
         //
         // TBD - when parent run is shorter than child?
         //       appears that parent end halts child?
         cout << "\n*** Parent complete ***" << '\n';
      }


private:

   void errnoExit(int err_no, const string message, int id) {
      assert(0 != err_no);  cerr << message << strerror(err_no);
      assert(id < 0);       exit(id); }

}; // class Kitchen


class Reception
{
public:
   Reception() = default;
   ~Reception() = default;

   int operator()(int argc, char* argv[]) { return run_shell(argc, argv); }

   //void repart(std::vector<Package> packed_order);
   //bool is_order(std::string input);
   //std::vector<Package> pack(std::string input);
   int run_shell(int /*argc*/, char** /*argv[]*/)
      {
         _kitchens.push_back(Kitchen());
         return (0);
      }
private:
   vector<Kitchen> _kitchens;
}; // class Reception


int main(int argc, char* argv[]) { return Reception()(argc, argv); }

Типичный вывод:

  i am parent, child_pid: 6727

  i am child: 0

  parent 1
  child  1
  parent 2
  child  2
  parent 3
  child  3
  parent 4
  child  4
  parent 5
  child  5
  parent 6
  child  6
  parent 7
  child  7
  parent 8
  child  8
  parent 9
  child  9
  parent 10
  child  10
  parent 11
  child  11
  parent 12
  child  12
  parent 13
  child  13
  parent 14
  child  14
  parent 15
  child  15
  parent 16
  child  16
  parent 17
  child  17
  parent 18
  child  18
*** Child  complete ***
  parent 19
  parent 20
  parent 21
  parent 22
  parent 23
  parent 24
  parent 25
  parent 26
  parent 27
  parent 28
*** Parent complete ***
0 голосов
/ 22 апреля 2019

Необходимо указать родительскому процессу дождаться завершения дочерних процессов. Я заметил, что в вашем последнем условии else отсутствуют скобки, поэтому будет выполнена только одна строка после else.

Другая проблема - указатель wstatus. Поскольку это указатель, который не инициализирован, я не уверен, какое поведение будет выражено. Измените его на int и в вызове waitpid используйте & wstatus.

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

В последнем случае отсутствуют фигурные скобки, waitpid(this->_pid, wstatus, 1); выполняется как дочерним, так и родительским ...

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