前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET Core、.NET 5/6 Linux 守护进程设计

.NET Core、.NET 5/6 Linux 守护进程设计

作者头像
郑子铭
发布2021-10-26 16:12:47
1.8K0
发布2021-10-26 16:12:47
举报
文章被收录于专栏:DotNet NB && CloudNative

链接:cnblogs.com/yunei/p/15367709.html

前言

几年前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是《.NET跨平台实践:用C#开发Linux守护进程》《.NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇》

由于当时.NET Core还很稚嫩,没有在业界得到广泛使用,所以之前这两篇文章的技术是针对Linux+Mon这个环境而言的。

现在.NET Core、.NET 5 已经大行其道,.NET 6也很快就会发行正式版,因此,很有必要再加一篇,阐述一下怎么让.NET Core以及.NET 5以上版本的.NET程序也能在Linux环境下,以自身的能力成为货真价实的Linux守护进程,而不是借用第三方工具!

这就是本文的初衷。

关于Linux Daemon程序的原理之类的,已经在之前的两篇文章中得到了一些体现,因此,本文就直接上代码,不在高大上的理论中去兜圈子了。

代码语言:javascript
复制
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守护进程的示例代码,你完全可以将它关键部分借用到自己的真实项目中。使用中如果有什么问题或建议,欢迎与本人作进一步交流。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档