![以编程方式在 Linux 中加载服务](https://linux22.com/image/47251/%E4%BB%A5%E7%BC%96%E7%A8%8B%E6%96%B9%E5%BC%8F%E5%9C%A8%20Linux%20%E4%B8%AD%E5%8A%A0%E8%BD%BD%E6%9C%8D%E5%8A%A1%20.png)
给定一个服务名称(由用户创建)及其路径,我如何在运行时从C++
Ubuntu 中的程序加载并启动该服务。
是否存在类似于、、等Windows
功能的 函数来执行此操作?CreateService
OpenSCManager
OpenService
答案1
对于初学者来说,这应该在 StackOverflow 上,而不是在这里。
您从 Windows 中了解到的带有服务的整个概念在 Linux 上根本不存在。
在 Windows 上,您的进程注册一个回调,服务控制管理器 (SCM) 使用该回调来初始化和控制您的服务。这样,可以处理发送到 SCM 的与您的服务相关的请求,例如暂停、停止、启动、恢复。
在 Linux 上,这个概念并不存在。最接近的是作为守护进程运行的程序。
任何程序都可以选择与其父程序分离(通过双分叉),也可以与终端分离。这基本上就是 Unix 上守护进程的要点。它是一个后台进程,但与 Windows 不同,没有特殊的第三方参与。
嗯,差不多了。该init
进程将确保进程被收集(并且退出后不会保留)。此外,通常一些初始化脚本(旧式)或初始化系统(systemd、upstart 等)将使用特殊语法来控制进程。为此,大多数守护进程可以选择将其进程 ID (PID) 存储在一个文件中,这样的脚本可以从该文件中读取它,然后使用该kill
程序发送信号来控制守护进程(即后台进程)的执行,以告诉它例如重新读取其配置或停止。
你会确实想要购买并阅读 Michael Kerrisk 的书《Linux 和 UNIX 系统编程权威指南》,如果您打算将开发扩展到其他 unixoid 平台(OSX),也许还可以选择 APUE(Unix 环境中的高级编程)等经典书籍,BSD ...)。
答案2
在类 UNIX 系统上,守护进程和常规进程是同一回事。他们之间有一条模糊的界限。从本质上讲,它们在语义上的分离不是因为它们的工作方式,而是因为您对它们的期望。守护进程只是一个在后台等待您与其通信、等待某些事件发生的进程。如果守护进程需要与用户通信,它本身负责建立通信:套接字(unix或inet)、被动观察文件系统、设备文件......守护进程通常由某种“服务管理器” - systemd 管理、upstart 或 systemV(这不是真正的管理,你只需保留一些 pid 文件来知道如何杀死它们,以及一些 init 脚本来以有序的方式启动它们)。这实际上取决于您想要实现的目标:
如果您想在目标系统的服务管理器下统一启动服务,那么您应该调用所选系统的控制命令(这取决于发行版,但 systemd 正变得越来越普遍)。例如,您只需调用systemctl start sshd
,sshd 就会启动。
如果您真的只是想要一个执行某些处理的后台进程,那么它根本就不是守护进程。如果您简单地fork
和exec
,您将创建另一个进程(您可以通过管道与其保持联系),并且您可以在退出时杀死该子进程,因此它会与您一起消亡(或者将其保留为孤儿,在这种情况下它会变成更多守护进程)。
您可以在子进程中双分叉并设置会话并关闭文件描述符,从而成为更合适的守护进程。
然而,这实际上取决于您想要实现的目标。您可能在这里问了错误的问题,并且您正在尝试做一些在 Linux 上甚至没有多大意义的事情。
答案3
我发现了类似的东西。一个简单的看门狗程序,通过 exec 函数运行服务。你可以找到它这里。
答案4
了解什么是服务
服务是在后台运行的进程。它们不具有交互性,没有控制终端。在 Linux 中,服务称为守护进程。
如何手动管理服务
通过终端
#run program that should be service, output_file stands for stdout output
./executable_path arg1 arg2 > output_file
#press CTRL-Z - stops process
#move process to the background, prints its PID
bg
#disown process or you may have started process with "nohup"
disown
现在你有了服务,你可以关闭终端,服务仍然会运行。
kill "PID print before
服务已经死了。
通过 shell 脚本
启动服务并将其 PID 保存到文件中的脚本。
nohup ./executable args > output &
MY_PID=$!
echo $MY_PID > some_folder/service_pid
关闭服务的脚本:
kill `cat some_folder/service_pid`
rm some_folder/service_pid
通过C++
您可以使用脚本执行与示例中相同的步骤。只需将其包装到 C 函数中,例如:system
,fork
和exec*
。然而,这是与编程相关的东西,而不是与 Linux 相关的(unix.stackexchange.com)。从c++中搜索创建过程。
与系统服务管理器集成
出色地。这相当困难,因为 Linux 有很多服务管理器,而且并不是每个 Linux 发行版都使用相同的服务管理器。用户也可以更改服务管理器,因此即使在同一发行版上,您也不能保证它将使用相同的服务管理器。
最常用的是暴发户和系统