如何使进程自动进入后台执行?

发布于 2022-09-06 02:58:35 字数 331 浏览 20 评论 0

我想让一个我自己写的一个后台进程自动进入后台执行,就像 nginx 命令一样,使用nginx start后,进程自动进入后台,让出终端

进程执行后再使用 ps 命令查询时,显示为nginx start这种。

自己有一个方法:

  1. 阻止进程的正常执行。
  2. 开启进程后,让进程再使用 nohup 开启一个子进程,并传入一个特殊参数使程序能正常执行。
  3. 修改这个子进程的名字。
  4. 退出父进程。

只是感觉方法有点不伦不类,求问有没有优雅点的方式。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧夏天 2022-09-13 02:58:35

这个其实很简单,你就是想实现一个守护进程。实现守护进程的方式有两种,一种在自己实现,一种是调用系统函数。
先说第二种系统调用,demo代码如下:

#include <unistd.h>

int main()
{
    //第一个参数0表示工作目录切换到"/"
    //第二个参数0表示重定向标准输入、标准输出、标准错误到"/dev/null"
    if (0 == daemon(0, 0))
    {
        while (1)
        {
            sleep(1);
        }
    }

    return 0;
}

现在让我们来看自己如何实现,实现守护进程的步骤如下:

编写daemon程序的步骤如下:
1.1 设置创建掩码为0,防止因为继承了父进程创建文件权限,而父进程又禁止某些权限,从而导致需要某些权限的创建操作失败。
1.2 调用fork,父进程退出,子进程继续运行。两点作用:父进程退出,让shell认为命令已经结束;此时生成的子进程不是进程组的组长进程,而这是调用setsid创建一个新会话的必要条件。
1.3 调用setsid,创建新会话,进程变成了会话首进程,新进程组的组长进程,并脱离终端。
1.4 切换工作目录为根目录,防止进程之前工作目录所在的文件系统无法被卸载。
1.5 关闭不再需要的文件描述符,这些文件描述符都是从父进程中继承过来的。
1.6 重定位标准输入,标准输出及标准出错到/dev/null(/dev/null就像是window的垃圾箱)。

demo代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/resource.h>

int daemon_init()
{
    int i;
    int fd0;
    int fd1;
    int fd2;
    pid_t pid;
    struct rlimit rl;
    struct sigaction sa;
    
    umask(0);
    
    if (getrlimit(RLIMIT_NOFILE, &rl) <0)
    {
        printf("call getrlimit error\n");
    }

    if ((pid = fork()) < 0)
    {
        printf("call fork error\n");
    }
    else if (pid != 0) //parent
    {
        exit(0);
    }
    setsid();

    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
    {
        printf("call sigaction error\n");
    }

    if ((pid = fork()) < 0)
    {
        printf("call fork error\n");
    }
    else if (pid != 0)
    {
        exit(0);
    }

    if (chdir("/") < 0)
    {
        printf("call chdir error\n");
    }

    if (rl.rlim_max == RLIM_INFINITY)
    {
        rl.rlim_max = 1024;
    }
    for (i = 0; i < rl.rlim_max; ++i)
    {
        close(i);
    }

    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);

    if (fd0 !=0 || fd1 != 1 || fd2 != 2)
    {
        printf("unexpectd file desc %d %d %d\n", fd0, fd1, fd2);
    }
    return 0;
}

int main()
{
    daemon_init();
    while (1)
    {
        sleep(1);
    }
    return 0;
}
放肆 2022-09-13 02:58:35

我觉得你没必要这么麻烦,现代化的系统都有服务管理功能,把程序按照服务方式运行就可以了,根本就不用自己去写一个daemon

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文