几年前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是《.NET跨平台实践:用C#开发Linux守护进程.NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇
这就是本文的初衷。
关于Linux Daemon程序的原理之类的,已经在之前的两篇文章中得到了一些表现,因此,本文就直接上代码,不再在高大上的理论中去兜圈子了。
using System;
using System.Threading;
using System.Timers;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;/************************************************* .Net Core/.Net5+ Linux Daemon示例,作者宇内流云 ************************************************/namespace daemon
{class Program{static unsafe void Main(string[] args){// 进入守护状态int pid = fork();if (pid != 0) exit(0);setsid();pid = fork();if (pid != 0) exit(0);umask(0);// 关闭所有打开的文件描述符int fd_nul = open("/dev/null", 0);for (var i = 0; i <= fd_nul; i++){if (i < 3)Dup2(fd_nul, i);elseclose(i);}// 进入主方法 // (本示例的功能很简单,就是定时向某个文件写入点内容) DaemonMain(args);}/// <summary>/// Daemon工作状态的主方法/// </summary>/// <param name="aargs"></param>static void DaemonMain(string[] aargs){//启动一个线程去处理一些事情(new Thread(DaemonWorkFunct) { IsBackground = true }).Start();//daemon时,控制台输入、输出流已经关闭// 因此,请不要再用Console.Write/Read等方法//阻止daemon进程退出(new AutoResetEvent(false)).WaitOne();}static FileStream fs;static int count = 0;static void DaemonWorkFunct(){try{fs = File.Open(Path.Combine("/tmp", "daemon.txt"), FileMode.OpenOrCreate);}catch{exit(1);return;}var t = new System.Timers.Timer() { Interval = 1000 };t.Elapsed += OnElapsed;t.Start();}private static void OnElapsed(object sender, ElapsedEventArgs e){var s = DateTime.Now.ToString("yyy-MM-dd HH:mm:ss") + "\n";var b = Encoding.ASCII.GetBytes(s);fs.Write(b, 0, b.Length);fs.Flush();count++;if (count > 100){fs.Close();fs.Dispose();exit(0);}}[DllImport("libc", SetLastError = true)]static extern int fork();[DllImport("libc", SetLastError = true)]static extern int setsid();[DllImport("libc", SetLastError = true)]static extern int umask(int mask);[DllImport("libc", SetLastError = true)]static extern int open([MarshalAs(UnmanagedType.LPStr)] string pathname, int flags);[DllImport("libc", SetLastError = true)]static extern int close(int fd);[DllImport("libc", SetLastError = true)]static extern int exit(int code);[DllImport("libc", EntryPoint = "dup2", SetLastError = true)]static extern int Dup2(int oldfd, int newfd);}
}
以上代码就是Linux环境中,.NetCore或.Net5以上版本的.net程序,以纯代码方式使自身成为标准的Linux守护进程的示例代码,你完全可以将它关键部分借用到自己的真实项目中。使用中如果有什么问题或建议,请加入本人的QQ群作进一点交流。
注:本文为 宇内流云 (邮箱:j66x@163.com)原创作品,用c#开发原生的Linux守护进程相关技术及代码亦属本人首发,如需转载,请注明出处和作者,同时,没有得到本人亲自同意,本文关键代码不得被“借鉴”到其他纸质作品中。