草庐IT

c - 编写 linux 守护进程

coder 2023-06-22 原文

在 Linux 下编写/配置应用程序的正确方法是什么,该应用程序一直运行并服务于外部请求(TCP、数据库、文件系统,任何类型)。

我特别不调用这个守护进程,因为它可能意味着我不希望它在 Linux 环境中调用它。

我已经阅读了多个主题,包括:

Linux daemonize

best way to write a linux daemon

Best practice to run Linux service as a different user

但它们都没有对使用哪种方法进行全面比较。

我看到以下选项:

  • 编写 fork 、调用 setpid、umask 等的应用程序,但这 需要应用程序自己执行许多步骤; (自动启动 通过 init.d?)
  • 使用 daemon() init.d 函数为您执行大部分这些步骤(但它是否可移植到所有/许多 linux 发行版)
  • 使用 & 运行应用程序并相信它在后台运行

但其中哪一个是要走的路。或者如果都可以用,那么linux中的daemon是什么?

我正在寻找相当于在 Windows 下作为服务运行的应用程序(并且任何 .exe 都可以使用 sc 自动生成作为服务运行)。


我的要求如下:

  • 开机后启动(自动)
  • 特定用户(非root)身份运行
  • 可以访问整个文件系统 (/),但可以作为运行应用程序的用户创建/修改文件
  • 可以通过服务启动服务停止来控制
  • 可能在崩溃或终止后自动重启
  • 可以写入系统日志
  • 在 RHEL7 下运行

我是该应用程序的作者,但不想更改它来处理守护进程。

我的猜测是编写自定义 init.d 脚本,该脚本反过来会调用/etc/init.d/functions 中的 daemon() 函数。我说得对吗?

最佳答案

RHEL7 使用 systemd 作为它的初始系统,它将满足您的大部分需求。你应该写一个 systemd unit file对于你的守护进程(在 systemd 的说法中称为 service)。然后它可以:

  • 自动启动:是的,使用 systemctl enable yourservice
  • 以特定用户身份运行:是的,设置一个User键入您的单元文件。
  • 可以访问整个文件系统:是的,它将拥有您配置的用户拥有的所有权限,并以该用户的身份创建文件。
  • 可以通过service start控制:是的,或者通过systemctl start
  • 崩溃后自动重启:是的,设置一个Restart在您的单元文件中输入关键字(例如,on-failurealways)。
  • 写入系统日志:您的程序写入标准输出的任何输出都会写入 systemd 日志,可以在其中使用 journalctl 查看。和/或根据需要写入系统日志。

您的应用程序不需要(也不应该)在现代初始化系统下运行时自行守护进程。这不仅适用于 systemd,也适用于 upstart,以及像 runit、daemontools、supervisord 和大多数其他东西这样的主管。守护进程有点挑剔而且容易出错。只需像往常一样编写您的应用程序,然后让 init 系统完成它的工作。

关于c - 编写 linux 守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37547826/

有关c - 编写 linux 守护进程的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  3. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  4. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  5. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

  6. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  7. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

  8. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  9. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

  10. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts

随机推荐