随着针对 Delphi 的 Linux 目标的引入,为 Delphi 开发人员提供了创建 Linux 服务器应用程序的广泛可能性。不幸的是,目前 RAD Studio IDE 提供的项目类型数量有限,而且这些项目类型不包括创建服务(或在 Linux 世界中称为守护程序)。
*注意*在这篇文章中,我假设您已经配置为将应用程序部署到 Linux 并了解如何从 Linux 命令行启动它。如果不是这种情况,请参阅我之前关于这些主题的帖子:
http://chapmanworld.com/2017/02/28/embarcadero-delphi-linux-bootcamp/
http://chapmanworld.com/2016/12/29/configure-delphi-and-redhat-or-ubuntu-for-linux-development/
在 Linux 操作系统下,守护进程只是一个可执行文件,它继续运行而忽略标准输入和输出流。也就是说,它们不接受来自键盘的输入,也不向屏幕显示数据(特殊情况除外)。因此,在不使用标准输入和输出的情况下继续在后台运行的应用程序是守护进程。
守护程序应用程序的另一个属性是它在后台运行。从 Linux 中的终端窗口运行的应用程序提供有标准的输入和输出流,因此在应用程序终止之前终端将无法使用。为了演示,创建一个新的命令行应用程序并将其源代码设置为如下所示……
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
begin
try
while true do sleep(100);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
如果您从命令行运行此应用程序,您会发现它进入了一个无限循环(while 循环),并且您无法重新获得对终端窗口的控制,直到您发出 [CTRL] + [C] 以中止应用。
现在让我们把这个应用程序变成一个守护进程。修改你的源代码如下……
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Posix.Unistd;
begin
try
if fork()<>0 then begin
exit;
end;
while true do sleep(100);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
现在,当您尝试从命令行运行此应用程序时,它将立即退出。看起来好像应用程序什么也没做。但是,发出指令:
ps -e
你应该看到这样的东西:
您会注意到“Project1”实际上仍在运行,只是被移到了后台。
作为旁注,您可以通过记下它的进程 ID(在我的情况下是屏幕截图中的 16898)并发出适当的终止指令来终止应用程序:
kill 16898
您现在可以使用守护程序中所需的任何应用程序逻辑替换无限 while 循环。
这是如何运作的?
这个工作的关键是“fork()”方法,可以在“Posix.Unistd”单元中找到。fork 方法是标准 posix API 的一部分,可以在此处找到谁的文档:https : //linux.die.net/man/3/fork
fork 所做的是创建任何进程调用它的副本,在我们的例子中是 Project1。
因此,在调用 fork 的那一刻,我们的应用程序要么在原始进程中继续执行,要么在复制进程中继续执行。
fork 调用的返回值告诉我们正在执行的进程的哪个实例。返回值零告诉我们我们正在子进程(副本)中执行,任何其他值告诉我们我们正在执行在父进程(发起者)中。其实fork的返回值不为零时,就是新创建的子进程的进程ID。当我们确定我们在父进程中时,我们只需调用“exit”退出应用程序,允许子副本继续进行无限 while 循环。
结论
此时,您可以创建守护程序应用程序。您可能希望更详细地研究 Linux (posix) API,以了解如何处理可用于正常终止应用程序的“信号”,而不是使用终止指令的蛮力终止。您可能还需要某种方式与您的守护进程通信。与进程通信的方法有很多,但 Delphi 开发人员最熟悉的方法可能是使用 TCP/IP。将您的服务转变为 TCP/IP 服务器将允许您向其发送数据和指令。
不管你决定用你的守护进程做什么,我希望你发现这个简短的教学有用。
谢谢阅读!
Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号
执行时间: 0.038568019866943 seconds