ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

.NET跨平台实践:.NetCore、.Net5/6 Linux守护进程设计

2021-10-04 23:32:18  阅读:176  来源: 互联网

标签:NetCore int libc 跨平台 static Linux true SetLastError


之前,我写过两篇关于用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;


/********************************************
 * 一个完整的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 execvp([MarshalAs(UnmanagedType.LPStr)] string file, string[] argv); [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守护进程的技术及代码亦属本人首发,如需转载,请注明出处和作者

 

标签:NetCore,int,libc,跨平台,static,Linux,true,SetLastError
来源: https://www.cnblogs.com/yunei/p/15367615.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有