随着Delphi的Linux目标的引入,Delphi开发人员可以使用各种各样的方式来创建Linux服务器应用程序。不幸的是,目前RAD Studio IDE提供的项目类型数量有限,并且其中不包括创建服务(或Linux世界中称为Daemon的服务)。
* note *在本文中,我假设您已经配置为将应用程序部署到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指令来终止该应用程序:
kill 16898
现在,您可以用守护程序中所需的任何应用程序逻辑替换无限while循环。
这是如何运作的?
这项工作的关键是“ fork()”方法,该方法可以在“ Posix.Unistd”单元中找到。fork方法是标准posix API的一部分,其文档可以在这里找到:https : //linux.die.net/man/3/fork
fork所做的是创建一个无论哪个进程都称为它的副本,在本例中为Project1。
因此,在调用fork的那一刻,我们的应用程序执行要么在原始过程中继续,要么在复制过程中继续。
fork调用的返回值告诉我们正在执行哪个进程实例。返回值为零表明我们正在子进程(副本)中执行,其他任何值告诉我们正在执行在父进程(发起者)中。实际上,当fork的返回不为零时,它是新创建的子进程的进程ID。当我们确定我们处于父进程中时,我们只需调用“退出”即可退出应用程序,从而允许子副本继续进入无限while循环。
结论
至此,您就可以创建守护程序了。您可能希望更详细地研究Linux(posix)API,以了解如何处理可用于正常终止应用程序的“信号”,而不是使用kill指令的强行终止。您可能还需要某种与守护进程进行通信的方法。与该过程进行通信的方法有很多,但是Delphi开发人员可能最熟悉的是使用TCP / IP。将服务转换为TCP / IP服务器将使您可以向其发送数据和指令。
无论您决定对守护程序做什么,我都希望您对本简要说明有所帮助。
Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号
执行时间: 0.21240401268005 seconds