Creating a Linux Daemon (service) in Delphi
With the introduction of the Linux target for Delphi, a wide range of possibilities are opened up to Delphi developers, to create Linux server applications. Unfortunately there are currently a limited number of project types available from the RAD Studio IDE, and those do not include creating a service (or Daemon as it’s called in the Linux world).
*note* In this post I am assuming you are already configured to deploy an application to Linux and understand how to launch it from the Linux command line. If this is not the case, see my earlier posts covering these subjects:
- 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/
Under the Linux operating system, a Daemon is simply an executable which continues running while ignoring the standard input and output streams. That-is, they do not accept input from the keyboard, and they do not present data to the screen (except in special circumstances). So an application which simply continues to run in the background without using the standard input and output, is a Daemon.
One other property of a Daemon application is that it runs in the background. Applications run from the terminal window in Linux are provided with the standard input and output streams, and therefore the terminal becomes unusable until the application terminates. To demonstrate, create a new command line application and set it’s source code to read as follows…
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.
If you run this application from the command line, you’ll find that it enters into an infinite loop (the while loop), and you do not regain control of the terminal window until you issue [CTRL] + [C] to abort the application.
Lets now turn this application into a Daemon. Alter your source code to read as follows…
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.
Now, when you attempt to run this application from the command line, it will immediately exit. It will appear as though the application did nothing. However, issue the instruction:
ps -e
and you should see something like this:
You’ll notice that “Project1” is actually still running, it’s simply been moved to the background.
As a side note, you can kill the application by making a note of it’s process ID (in my case 16898 from the screenshot) and issuing the appropriate kill instruction:
kill 16898
You could now replace the infinite while loop with whatever application logic you need within your daemon.
How does this work?
The key to this working is the “fork()” method, which can be found in the unit “Posix.Unistd”. The fork method is a part of the standard posix API, who’s documentation may be found here: https://linux.die.net/man/3/fork
What fork does is to create a copy of which-ever process calls it, in our case Project1.
So at the moment fork is called, our application execution either continues in the originating process, or it continues in the copy process.
The return value of the call to fork tells us which instance of the process we are executing in. A return value of zero tells us that we are executing in the child process (the copy), and any other value tells us that we are executing in the parent process (the originator). In fact, when the return of fork is not zero, it is the process ID of the newly created child process. We simply call ‘exit’ to exit the application when we determine that we are in the parent process, allowing the child copy to proceed on to the infinite while loop.
Conclusion
At this point you are able to create daemon applications. You may wish to research the Linux (posix) API’s in a little more detail to see how to handle ‘signals’ which may be used to gracefully terminate your application, rather than using the brute force termination of a kill instruction. You might also want some way to communicate with your daemon process. There are many ways to communicate with the process, but possibly the most familiar to a Delphi developer would be to use TCP/IP. Turning your service into a TCP/IP server would allow you to send data and instructions to it.
Regardless of what you decide to do with your daemon, I hope you found this brief instructional useful.
http://chapmanworld.com/2017/04/05/creating-a-linux-daemon-service-in-delphi/
Creating a Linux Daemon (service) in Delphi的更多相关文章
- Linux daemon与service 学习笔记
service 常驻在内存中的进程,且可以提供一些系统或网络功能,就是服务. daemon service的提供需要进程的运行,所以实现service的程序我们称为daemon. eg: 实现 ...
- [转] Linux Daemon Writing HOWTO
Linux Daemon Writing HOWTO Devin Watson v1.0, May 2004 This document shows how to write a daemon in ...
- Linux命令service - 系统服务管理(转)
用途说明 service命令用于对系统服务进行管理,比如启动(start).停止(stop).重启(restart).查看状态(status)等.相关的命令还包括chkconfig.ntsysv等,c ...
- Azure的CentOS上安装LIS (Linux Integration Service)
Azure上虚拟化技术都是采用的Hyper-v,每台Linux虚拟机都安装了LIS(Linux Integration Service).LIS的功能是为VM提供各种虚拟设备的驱动.所以LIS直接影响 ...
- 创建 SysV 风格的 linux daemon 程序
本文介绍如何使用 C 语言创建 Linux 系统中 SysV 风格的 daemon 程序.注意:这是一种旧式的 daemon 程序写法,进入 systemd 时代后是不需要通过这样的方式创建 daem ...
- 在 CentOS7 上将自定义的 jar 包注册为 linux 服务 service
在 CentOS7 上将自定义的 jar 包注册为 linux 服务 service 1.在 /etc/rc.d/init.d/ 目录下创建一个名字和服务名完全相同的 shell 脚本文件 joyup ...
- 将Apache加入到linux系统service
将Apache加入到linux系统service 将apache加入到linux系统服务,用service命令来控制apache的启动和停止. 本文由乌合之众瞎写http://www.cnblogs. ...
- 时隔两年最近再次折腾opensuse 的一些笔记 - opensuse linux java service shell
时隔两年最近再次折腾opensuse 的一些笔记 - opensuse linux java service shell opensuse 一些常用命令: service xxx start/s ...
- Linux: service network/Network/NetworkManager
Linux:service network/Network/NetworkManager start 这三种有什么不同? 1.network service的制御网络接口配置信息改动后,网络服务必须从 ...
随机推荐
- STL源代码学习--vector用法汇总
一.容器vector 使用vector你必须包含头文件<vector>: #include<vector> 型别vector是一个定义于namespace std内的templ ...
- XMPP开发adiumclient登陆
我写在前面client它已经实现了登陆,我用下面的adium要登录落实的朋友加入,而自己写的client在聊天帐号. 第一次登录时adium工欲善其事,必先例如,下面的配置 保存后.你会发现自己的账号 ...
- 关于HierarchyViewer的使用
在学习ViewGroup和Layout时我们可能会有一个疑问,如果我在Xml布局文件中不放置Layout,直接放TextView等组件的时候,它是用什么方式布局的?还有要学习别人优秀的布局怎么办? H ...
- React Native中的DeviceEventEmitter.addListener与DeviceEventEmitter.emit
官方文档没有对这两个方法做很好的解释,需要自己找资料研究.看了几篇文章,总结是和订阅发布模式差不多,用来事件监听发送的. React Native学习之DeviceEventEmitter传值 R ...
- javascript对象属性为空的判断
zepto: $.isEmptyObject = function(obj) { var name for (name in obj) return false return true } $.isE ...
- wxWidgets谁刚开始学习指南(5)——使用wxSmith可视化设计
wxWidgets谁刚开始学习的整个文件夹指南 PDF版及附件下载 1 前言2 下载.安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用w ...
- Objective-C block实现代码分析
block内部结构 让我们写一个block void exampleBlock() { // NSConcreteStackBlock int a = 1; __block int b = 2; in ...
- 关于java中继承抽象类和实现接口的区别
简单来说,继承就是“是不是”,实现就是“有没有”.(一个大神说的,我觉得很生动很形象 海子大神链接http://www.cnblogs.com/dolphin0520/p/3811437.html)
- C#中的字符串——用Stringbuilder类很重要
注:这篇文章基本是<C#高级编程>(第七版)第九章的学习笔记. 众所周知,C#中处理字符串通常用的都是string,它其实是.NET基础类System.String类的映射.注意一个是小写 ...
- 在WPF中制作正圆形公章
原文:在WPF中制作正圆形公章 之前,我利用C#与GDI+程序制作过正圆形公章(利用C#制作公章 ,C#制作公章[续])并将它集成到一个小软件中(个性印章及公章的画法及实现),今天我们来探讨一下WPF ...