之前,我写过两篇关于用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守护进程的完整技术亦属本人首发,如需转载,请注明出处和作者

最新文章

  1. ServiceStack.OrmLite中的一些&quot;陷阱&quot;(2)
  2. 验证码的种类与实现 C#封装类 - .NET MVC WEBFORM
  3. 传智播客JavaWeb day09-mysql入门、数据库操作、数据库表操作、数据行操作
  4. hdu 4607 树的直径
  5. myeclipse连接数据库遇到的几个问题
  6. unity3d 版本问题
  7. 【转】MAT(Memory Analyzer Tool)工具入门介绍
  8. 安卓---高德地图API应用
  9. WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置
  10. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(二)示例
  11. JS实现倒计时
  12. go并发调度原理学习
  13. Python爬虫之12306-买票器小白源码
  14. Oracle to_char(参数,&#39;FM990.00&#39;)函数
  15. VM虚拟机ubantu自适应屏幕大小
  16. MyBatis源码解析【7】接口式编程
  17. Eureka与ZooKeeper 的比较(转)
  18. jQueryMobile的按钮样式
  19. python中 除了if else def class 有作用域 其余没有作用域
  20. 修改mysql的用户密码

热门文章

  1. 初识apache DBCP连接池
  2. Java程序设计学习笔记(三)—— IO
  3. go进阶--测试
  4. springboot开启矩阵传参MatrixVariable
  5. Java网络编程之TCP
  6. idea快速搭建Tomcat服务器
  7. vue JS获取当前时间并格式化 ( 前端小细节,大进步 )
  8. mybaits源码分析--binding模块(五)
  9. Python之win32模块
  10. WEB漏洞——文件上传