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

问题描述 投票:-1回答:3

我已经创建了一个应该处理子进程的类但是当我把测试打印放在里面没有任何反应时,有人可以告诉我为什么吗?

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

现在只有父母打印我希望两个进程打印的位置。

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

c++ class fork
3个回答
1
投票

现在好些吗?

是的,更好。


我将你的代码复制到我的Lubuntu 18.04,并使用g ++ 7.3.0-27,得到了编译的东西。

我系统上复制的代码重现了您的错误。

嗯。

所以,我去寻找,并迅速找到了我最近用叉子做的实验。我不明白它为什么会起作用,而你的不行,它们看起来与我相似。

我使用一个开关而不是嵌套的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
投票

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


0
投票

需要告知父进程等待任何子进程完成。我注意到你的最后一个条件是缺少括号,所以只有else之后的一行才会被执行。

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

© www.soinside.com 2019 - 2024. All rights reserved.