为什么这个班级的孩子不打印?

时间:2019-04-22 12:06:41

标签: c++ class fork

我制作了一个应该处理子流程的类,但是当我将测试打印内容放进去时,没有人可以告诉我为什么吗?

我尝试了不同类型的打印以及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;
};

Reception.cpp

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

Reception.hpp

#pragma once

#include <iostream>
#include <sstream>
#include "Kitchen.hpp"

class Reception
{
    public:
        Reception();
        ~Reception();
        void repart(std::vector<Package> packed_order);
        bool is_order(std::string input);
        std::vector<Package> pack(std::string input);
        int run_shell(void);
    private:
        std::vector<Kitchen> _kitchens;
};

main.cpp

int main(void)
{
    Reception reception;
    return (reception.run_shell());
}

现在,只有父级在我希望两个进程都进行打印的地方进行打印。

请注意,此代码在类之外起作用。

3 个答案:

答案 0 :(得分:1)

  

现在好了吗?

是,更好。


我将您的代码复制到了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 ***

答案 1 :(得分:0)

最后一个没有花括号,waitpid(this->_pid, wstatus, 1);由孩子和父母共同执行...

答案 2 :(得分:0)

需要告知父进程等待所有子进程完成。我注意到您的最终else条件缺少括号,因此仅执行else后面的一行。

另一个问题是指针wstatus。因为它是未初始化的指针,所以我不确定会表达哪种行为。将其更改为int并在waitpid调用中使用&wstatus。