【问题标题】:Why am I having to terminate my program manually?为什么我必须手动终止我的程序?
【发布时间】:2014-09-21 07:03:55
【问题描述】:

我有一个程序应该启动另一个进程并与之同时工作。我正在使用fork()system() 来完成此操作。我有代码验证我的system() 调用是否返回,但每次执行时我都必须通过键入ctrl c 手动结束执行。我可以说我的一个进程终止了,但我不太确定是哪一个。我相信是父母。两者都应该被 return 语句捕获。

这里是父进程代码(forkWaitTest):

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

int main(void)
{
        pid_t childPID;
        int status;

        childPID = fork();
        if(childPID >=0)
        {
                if(childPID == 0)
                {
                        cout <<"I'm the fork child";
                        cout.flush();
                        status=system("child");
                        cout << "status = " << status;
                        //exit(0);
                        //cout << "Am I getting here?";
                }
                else{
                cout << "I am the parent and can keep doing things ";
                int y=1;
                int x=7;
                cout<< y+x << " ";
                }
        }
        return 0;
}

这是被调用的子进程

#include <stdio.h>

int main(int argc, char *argv[] )
{

  printf("I am the child\n");
  return 0;
}

这是我的输出:

-bash-4.2$ forkWaitTest
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child
status = 0

【问题讨论】:

  • 您如何确定某事“永不终止”?
  • 我必须推动 ctrl c 才能结束
  • 你的父母应该为孩子wait()ing,虽然我不能立即明白为什么不这样做会导致这种行为。
  • 我希望父进程与system 调用的子进程同时运行。最终我不得不把它变成我课程的客户端服务器程序。一个要求是我的客户启动我的服务器

标签: c++ fork terminate


【解决方案1】:

您的父母确实终止了。让我们看看你的输出:

-bash-4.2$ forkWaitTest
I am the parent and can keep doing things 8 I'm the fork child-bash-4.2$ I am the child
status = 0

现在让我们更仔细地看一下,尤其是这一点:

I'm the fork child-bash-4.2$

看,就在中间,上面写着bash-4.2$。那是父级终止后的命令提示符。然后孩子运行并退出,但你很困惑,因为它在 bash 提示符后打印。您的 ^C 仅打印下一行。

要验证,请按几次回车而不是^C

【讨论】:

  • 哇哦。所以它实际上结束它只是看起来不像它?哇,我觉得很傻。谢谢!这是我第一次处理同时运行的多个进程
【解决方案2】:

确保您的消息以换行符结尾(例如,在输出中添加 &lt;&lt; endl)。

我看到您的 bash 提示(-bash-4.2$)与其他输出混合在一起,部分原因是您的输出中没有换行符,部分原因是您的代码没有显示任何等待孩子的尝试去死。这意味着您的进程确实死了。

您可以输入:ls -l,shell 将执行该命令,因为它正在等待您输入某些内容。当您中断它(shell)时,它会再次提示,但即使没有中断它也会接受您的输入。


带有child的略微修改版本:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
  printf("I am the walrus (%d)\n", (int)getpid());
  return 0;
}

以及稍微修改的父版本:

#include <cstdlib>
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

int main(void)
{
    pid_t childPID;
    int status;

    childPID = fork();
    if (childPID >= 0)
    {
        if (childPID == 0)
        {
            cout << "I'm the forked child (" << getpid() << ")\n";
            cout.flush();
            status = system("child");
            cout << "status = " << status << endl;
            cout << "Am I getting here?\n";
            return 0;
        }
        else
        {
            cout << "I am the parent and can keep doing things ";
            int y = 1;
            int x = 7;
            cout << y + x << endl;
        }
    }
    int corpse;
    while ((corpse = wait(&status)) != -1)
        cout << "PID " << corpse << " exited with status " << status << endl;
    return 0;
}

提示Osiris JL:,我得到的输出示例是:

Osiris JL: ./parent
I am the parent and can keep doing things 8
I'm the forked child (3192)
I am the walrus (3193)
status = 0
Am I getting here?
PID 3192 exited with status 0
Osiris JL:

请注意,“子”程序由父进程自己的子进程的子进程运行(这就是打印 getpid() 值的原因)。而父进程循环中的wait() 确保子进程在父进程死亡之前就已经死亡。给定子进程的结构,它使用system() 函数,孙子进程(运行部分错误命名的child 进程)在子进程退出之前就在父进程退出之前退出。省略 wait() 循环,父母可以在孩子和孙子之前轻松退出:

Osiris JL: ./parent
I am the parent and can keep doing things 8
I'm the forked child (3207)
Osiris JL: I am the walrus (3208)
status = 0
Am I getting here?
ls -ld parent* child*
-rwxr-xr-x  1 jleffler  staff  8784 Sep 20 15:57 child
-rw-r--r--  1 jleffler  staff   122 Sep 20 15:57 child.cpp
drwxr-xr-x  3 jleffler  staff   102 Sep 20 15:57 child.dSYM
-rwxr-xr-x  1 jleffler  staff  9808 Sep 20 16:02 parent
-rw-r--r--  1 jleffler  staff   858 Sep 20 16:02 parent.cpp
drwxr-xr-x  3 jleffler  staff   102 Sep 20 16:02 parent.dSYM
Osiris JL: 

【讨论】:

  • 好吧,我做到了,但它所做的只是重新格式化我的输出。它没有其他任何帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多