теперь лучше?
Да, лучше.
Я скопировал ваш код в 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 ***