其他
.NET Core、.NET 5/6 Linux 守护进程设计
↓推荐关注↓
前言
几年前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是《.NET跨平台实践:用C#开发Linux守护进程》和《.NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇》。
由于当时.NET Core还很稚嫩,没有在业界得到广泛使用,所以之前这两篇文章的技术是针对Linux+Mono这个环境而言的。
现在.NET Core、.NET 5 已经大行其道,.NET 6也很快就会发行正式版,因此,很有必要再加一篇,阐述一下怎么让.NET Core以及.NET 5以上版本的.NET程序也能在Linux环境下,以自身的能力成为货真价实的Linux守护进程,而不是借用第三方工具!
这就是本文的初衷。
关于Linux Daemon程序的原理之类的,已经在之前的两篇文章中得到了一些体现,因此,本文就直接上代码,不在高大上的理论中去兜圈子了。
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);
else
close(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", SetLastError = true)]
static extern int dup2(int oldfd, int newfd);
}
}
以上代码就是Linux环境中.NET Core或.NET 5以上版本的.NET 程序,以纯代码方式使自身成为标准的Linux守护进程的示例代码,你完全可以将它关键部分借用到自己的真实项目中。使用中如果有什么问题或建议,欢迎与本人作进一步交流。
转自:宇内流云
链接:cnblogs.com/yunei/p/15367709.html
- EOF -
看完本文有收获?请转发分享给更多人
推荐关注「DotNet」,提升.Net技能
点赞和在看就是最大的支持❤️