【问题标题】:Launching a service from c++ with execv使用 execv 从 C++ 启动服务
【发布时间】:2014-06-24 15:15:05
【问题描述】:

我正在尝试从 c++ 启动一个 linux 服务并且我成功了,但是我的一个进程被标记为“已失效”,我不希望我的父进程死掉。

我的代码是(testRip.cpp):

int main()
{
    char* zebraArg[2];
    zebraArg[0] = (char *)"zebra";
    zebraArg[1] = (char *)"restart";

    char* ripdArg[2];
    ripdArg[0] = (char *)"ripd";
    ripdArg[1] = (char *)"restart";

    pid_t ripPid;
    pid_t zebraPid;

    zebraPid = fork();
    if(zebraPid == 0)
    {
        int32_t iExecvRes = 0;
        iExecvRes = execv("/etc/init.d/zebra", zebraArg);
        return 0;

        if(iExecvRes == -1)
        {
        ::syslog((LOG_LOCAL0 | LOG_ERR),
            "zebra process failed \n");
        }
    }
    else
    {
        while(1)
        {
                ::syslog((LOG_LOCAL0 | LOG_ERR),
                 "running\n");
            sleep(2);
        }
    }
}

ps -e 命令的退出是:

9411 pts/1    00:00:00 testRip
9412 pts/1    00:00:00 testRip <defunct>
9433 ?        00:00:00 zebra

/etc/init.d/zebra 将服务作为守护进程或类似的东西启动,所以我认为这是诀窍,但是:

为什么有 3 个进程,其中一个被标记为已失效? 我的代码有什么问题? 我该如何解决?

提前致谢。

【问题讨论】:

标签: c++ linux service daemon execv


【解决方案1】:

要删除僵尸,父进程必须wait() 其子进程,否则将死亡。如果您需要创建非阻塞 wait(),请查看带有 W_NOHANG 标志的 waitpid()。

【讨论】:

  • 嗨 Jean-Baptiste,我不能使用 wait 或 waitpid,因为进程的 PID 变得无效,这些进程是僵尸,所以它们已经完成,它们的 PID 不存在。
  • 进程在某些时候有一个PID——即使只是短暂的——它成为僵尸的原因之一是它没有父进程(以及其他一些东西)。一个进程设置正常但没有父进程的默认行为是让“init”获得所有权,这样它就不会变成僵尸。
  • 没有僵尸有PID!这正是它们存在的原因,它们只是它们过去存在的简单痕迹。无论如何,如果您不知道 PID(因为您忘记了),那么您可以使用 wait(NULL); 进行“匿名”等待。
【解决方案2】:

在 Unix 和 Linux 中正确地分叉一个守护进程是很困难的,因为有很多细节需要正确处理,而且顺序也很重要。在这种情况下,我怀疑是打开文件描述符的组合而不是分离控制终端。

我强烈建议从另一个程序中使用经过良好调试的实现 - 其中一个功能减少的命令行 shell(如 rsh 或 ksh)可能是一个不错的选择,而不是尝试烘焙您自己的版本。

【讨论】:

  • 感谢您的回复 rivimey,但不幸的是,由于合同问题,我需要实施自己的版本。我将使用“系统”调用启动服务,因为我始终是 root,我将尝试使用 WIFSIGNALED、WTERMSIG 和 WTERMSIG 捕获系统错误
  • 那里也有公共领域的外壳:我认为“pdksh”是其中之一:我希望它们将不受所有法律限制。您无需复制代码,但对其进行审查将是建设性的。
猜你喜欢
  • 2021-10-30
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 2016-04-10
  • 1970-01-01
相关资源
最近更新 更多