我正在编写一个Linux守护程序.我找到了两种方法.

  1. 通过调用fork()并设置sid来监控进程.
  2. &美元运行你的程序.

哪种方法正确?

推荐答案

http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

以下是成为守护进程的步骤:

  1. fork()以便父级可以退出,这会将控制权返回到调用程序的命令行或shell.此步骤是必需的,以确保新流程不会成为流程组长.如果您是流程组长,下一步setsid()将失败.
  2. setsid()成为流程组和会话组组长.由于一个控制终端与一个会话相关联,而这个新会话还没有获得一个控制终端,所以我们的进程现在没有控制终端,这对守护进程来说是件好事.
  3. 再次使用fork(),以便家长(会话组组长)可以退出.这意味着,作为非会话组组长,我们永远无法重新获得控制终端.
  4. chdir("/"),以确保我们的进程不会使用任何目录.如果不这样做,管理员可能无法卸载文件系统,因为它是我们当前的目录.[等效地,我们可以更改到包含对守护程序操作重要的文件的任何目录.]
  5. umask(0),这样我们就可以完全控制我们所写的任何东西的权限.我们不知道我们可能继承了什么.[此步骤是可选的]
  6. 关闭()fds 0、1和2.这将释放我们从父进程继承的标准输入、输出和错误.我们无法知道这些FD可能被重定向到了哪里.请注意,许多守护进程都使用sysconf()来确定限制_SC_OPEN_MAX._SC_OPEN_MAX告诉您最大打开文件/进程数.然后在循环中,守护进程可以关闭所有可能的文件描述符.你必须决定是否需要这样做.如果您认为可能有打开的文件描述符,您应该关闭它们,因为并发文件描述符的数量是有限的.
  7. 为stdin、stdout和stderr建立新的开放描述符.即使你不打算使用它们,打开它们仍然是一个好主意.对这些问题的精确处理取决于品味;例如,如果您有一个日志(log)文件,您可能希望将其作为stdout或stderr打开,并将"/dev/null"作为stdin打开;或者,您可以将"/dev/console"作为stderr和/或stdout打开,将"/dev/null"作为stdin打开,或者对特定守护进程有意义的任何其他组合.

更好的是,只要调用daemon()函数就可以了.

Linux相关问答推荐

Bash脚本用于在远程工作后关闭用户会话

GO:当使用NewManager调用创建cgroup时,权限被拒绝

仅使用Find搜索32字符长的目录

boost-iostreams 1.59 sparc-solaris 交叉编译失败

重新运行时避免 Linux bash 脚本中的文件重命名重复

在具有不同文件类型的文件夹中编辑多个 xml 文件 - 使用预定顺序

如何拆分和计算 Bash 中单词的出现次数?

erlang 格式的 utf8 变为 \x(反斜杠 x)ascii 编码

从 curl 命令输出中获取值

如何拆分多个分隔符但将它们保留在方括号之间?

使用 awk 从文件中检索一组特定的字符串

为什么 perf 不报告缓存未命中?

如何在 Linux 命令行上解析 CSV 文件?

在不调试的情况下查找哪个汇编指令导致了非法指令错误

使用 C/C++ (GCC/G++) 在 Linux 中的套接字编程中发送和接收文件

你如何在 C 中的 Linux 上进行非阻塞控制台 I/O?

`是什么意思! -d` 在这个 Bash 命令中?

区分 Windows 和类 Unix 系统的 Makefile

如何等待第一个命令完成?

初学者如何在 Linux 中开始使用 Mono?