之前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是《.NET跨平台实践:用C#开发Linux守护进程》和《.NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇》。由于当时.net core还很稚嫩,没有在业界得到广泛使用,因此,这两篇文章是的技术针对Linux+Mono这个环境而言的,现在,.Net Core、.Net5已经大行其道,.Net6也很快就会发行正式版,因此,有必要再加一篇,让.net core、.net5以上版本的.net程序也能在Linux环境下,以自身的能力成为Linux真正的守护进程,而不是借用第三方工具!

这就是本文的初衷。

关于Linux Daemon程序的原理之类的,已经在之前的两篇文章中写得很清楚发,因此,本文就直接上代码,不必在这样哪样的理论中去兜圈子。

  1. using System;
  2. using System.Threading;
  3. using System.Timers;
  4. using System.Runtime.InteropServices;
  5. using System.IO;
  6. using System.Text;
  7.  
  8. /********************************************
  9. * 一个完整的linux daemon示例,作者宇内流云 *
  10. ********************************************/
  11.  
  12. namespace daemon
  13. {
  14. class Program
  15. {
  16.  
  17. static unsafe void Main(string[] args)
  18. {
  19.  
  20. // 进入守护状态
  21. int pid = fork();
  22. if (pid != 0) exit(0);
  23. setsid();
  24. pid = fork();
  25. if (pid != 0) exit(0);
  26. umask(0);
  27.  
  28. // 关闭所有打开的文件描述符
  29. int fd_nul = open("/dev/null", 0);
  30. for (var i = 0; i <= fd_nul; i++)
  31. {
  32. if (i < 3)
  33. Dup2(fd_nul, i);
  34. else
  35. close(i);
  36. }

  37. // 进入主方法
    // (本示例的功能很简单,就是定时向某个文件写入点内容)
    DaemonMain(args);
  38.  
  39. }
  40.  
  41. /// <summary>
  42. /// Daemon工作状态的主方法
  43. /// </summary>
  44. /// <param name="aargs"></param>
  45. static void DaemonMain(string[] aargs)
  46. {
  47. //启动一个线程去处理一些事情
  48. (new Thread(DaemonWorkFunct) { IsBackground = true }).Start();
  49.  
  50. //daemon时,控制台输入、输出流已经关闭
  51. // 因此,请不要再用Console.Write/Read等方法
  52.  
  53. //阻止daemon进程退出
  54. (new AutoResetEvent(false)).WaitOne();
  55.  
  56. }
  57.  
  58. static FileStream fs;
  59. static int count = 0;
  60. static void DaemonWorkFunct()
  61. {
  62. try
  63. {
  64. fs = File.Open(Path.Combine("/tmp", "daemon.txt"), FileMode.OpenOrCreate);
  65. }
  66. catch
  67. {
  68. exit(1);
  69. return;
  70. }
  71.  
  72. var t = new System.Timers.Timer() { Interval = 1000 };
  73. t.Elapsed += OnElapsed;
  74. t.Start();
  75. }
  76. private static void OnElapsed(object sender, ElapsedEventArgs e)
  77. {
  78.  
  79. var s = DateTime.Now.ToString("yyy-MM-dd HH:mm:ss") + "\n";
  80. var b = Encoding.ASCII.GetBytes(s);
  81. fs.Write(b, 0, b.Length);
  82. fs.Flush();
  83.  
  84. count++;
  85. if (count > 100)
  86. {
  87. fs.Close();
  88. fs.Dispose();
  89. exit(0);
  90. }
  91.  
  92. }
  93.  
  94. [DllImport("libc", SetLastError = true)]
  95. static extern int fork();
  96.  
  97. [DllImport("libc", SetLastError = true)]
  98. static extern int setsid();
  99.  
  100. [DllImport("libc", SetLastError = true)]
  101. static extern int umask(int mask);
  102.  
  103. [DllImport("libc", SetLastError = true)]
  104. static extern int open([MarshalAs(UnmanagedType.LPStr)] string pathname, int flags);
  105.  
  106. [DllImport("libc", SetLastError = true)]
  107. static extern int close(int fd);
  108.  
  109. [DllImport("libc", SetLastError = true)]
  110. static extern int exit(int code);
  111.  
  112. [DllImport("libc", SetLastError = true)]
  113. static extern int execvp([MarshalAs(UnmanagedType.LPStr)] string file, string[] argv);
  114.  
  115. [DllImport("libc", EntryPoint = "dup2", SetLastError = true)]
  116. static extern int Dup2(int oldfd, int newfd);
  117.  
  118. }
  119. }

以上代码就是Linux环境中,.NetCore或.Net5以上版本的.net程序,以纯代码方式使自身成为标准的Linux守护进程的示例代码,你完全可以将它关键部分借用到自己的真实项目中。使用中如果有什么问题或建议,请加入本人的QQ群作进一点交流。

注:本文为 宇内流云 (邮箱:j66x@163.com)原创作品,用c#开发Linux守护进程的完整技术亦属本人首发,如需转载,请注明出处和作者

.NET跨平台实践:.NetCore、.Net5/6 Linux守护进程设计的更多相关文章

  1. .NET跨平台实践:再谈用C#开发Linux守护进程

    Linux守护进程是Linux的后台服务进程,相当于Windows服务进程,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是开发守护进程,还可以拓展 ...

  2. .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇

    Linux守护进程是Linux的后台服务进程,相当于Windows服务,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展 ...

  3. .NET跨平台实践:用C#开发Linux守护进程

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

  4. .NET跨平台实践:用C#开发Linux守护进程(转)

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

  5. .NET跨平台实践:用C#开发Linux守护进程-Daemon

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

  6. [转]❲阮一峰❳Linux 守护进程的启动方法

    ❲阮一峰❳Linux 守护进程的启动方法 "守护进程"(daemon)就是一直在后台运行的进程(daemon). 本文介绍如何将一个 Web 应用,启动为守护进程. 一.问题的由来 ...

  7. Server Develop (七) Linux 守护进程

    守护进程 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装 ...

  8. Linux 守护进程和超级守护进程(xinetd)

    一 .Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的 ...

  9. Linux守护进程详解(init.d和xinetd) [转]

    一 Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台 的守护进程来执行的 ...

随机推荐

  1. 【java虚拟机】常用的jvm配置参数

    转自:https://www.cnblogs.com/pony1223/p/8661219.html 零.在IDE的后台打印GC日志: 既然学习JVM,阅读GC日志是处理Java虚拟机内存问题的基础技 ...

  2. PE分析

    1 #include<windows.h> 2 #include<RichEdit.h> 3 #include "resource.h" 4 5 6 7 B ...

  3. 三 MongoDB进阶

    1 Limit方法 概念:查询指定数量的数据,该方法接受一个数字参数作为查询记录数的数量 举个例子:查询集合col中最多2条记录数 2 Skip方法 概念:查询到的结果集中,跳过指定数量的数据,该方法 ...

  4. Spring中常用重要的接口

    Spring (ApplicationContext 初始化Bean的方法 refresh()) public void refresh() throws BeansException, Illega ...

  5. Spring之JDBC Template

    时间:2017-2-5 18:16 --Spring对不同持久化技术的支持Spring为各种支持的持久化技术都提供了简单操作的模板和回调.ORM持久化技术:    JDBC:        org.s ...

  6. JDBC中级篇(MYSQL)——模拟从数据库中上传下载附件

    注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package b_blob_clob; import java.io.BufferedOutputStream; import j ...

  7. Go: 复合数据类型struct

    结构体 结构体是将零个或多个任意类型的命名变量组合在一起的聚合数据类型.每个变量都叫做结构体的成员. type Employee struct { ID int Name string age int ...

  8. Ubuntu 16.04 + python3 源码 安装+使用labelImg最新版

    安装 sudo apt-get update sudo apt-get upgrade sudo apt install python3-pip git clone https://github.co ...

  9. Mybatis笔记(3)

    一.多表查询 1.1 一对一查询 订单和用户(一个订单属于一个) Order实体类有user属性 配置resultMap(OrderMap) <select id="findAll&q ...

  10. Jest中Mock网络请求

    Jest中Mock网络请求 最近需要将一个比较老的库修改为TS并进行单元测试,修改为TS还能会一点,单元测试纯粹是现学现卖了,初学Jest框架,觉得在单元测试中比较麻烦的就是测试网络请求,所以记录一下 ...