.NET跨平臺實踐:.NetCore、.Net5/6 Linux守護程式設計

宇內流雲發表於2021-10-05

幾年前,我寫過兩篇關於用C#開發Linux守護程式的技術文章,分別是《.NET跨平臺實踐:用C#開發Linux守護程式》和《.NET跨平臺實踐:再談用C#開發Linux守護程式 — 完整篇》。由於當時.net core還很稚嫩,沒有在業界得到廣泛使用,所以之前這兩篇文章的技術是針對Linux+Mono這個環境而言的。現在,.Net Core、.Net5已經大行其道,.Net6也很快就會發行正式版,因此,很有必要再加一篇,闡述一下怎麼讓.net core以及.net5以上版本的.net程式也能在Linux環境下,以自身的能力成為貨真價實的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); 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", EntryPoint = "dup2", SetLastError = true)] static extern int Dup2(int oldfd, int newfd); } }

以上程式碼就是Linux環境中,.NetCore或.Net5以上版本的.net程式,以純程式碼方式使自身成為標準的Linux守護程式的示例程式碼,你完全可以將它關鍵部分借用到自己的真實專案中。使用中如果有什麼問題或建議,請加入本人的QQ群作進一點交流。

注:本文為 宇內流雲 (郵箱:j66x@163.com)原創作品,用c#開發原生的Linux守護程式相關技術及程式碼亦屬本人首發,如需轉載,請註明出處和作者,同時,沒有得到本人親自同意,本文關鍵程式碼不得被“借鑑”到其他紙質作品中

 

相關文章