Created
April 25, 2017 01:54
-
-
Save codeyu/629e21653646ca378db0d7a0d54d1497 to your computer and use it in GitHub Desktop.
一个完整的linux daemon示例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
using System.Timers; | |
using System.Runtime.InteropServices; | |
using System.IO; | |
using System.Text; | |
/******************************************** | |
* 一个完整的linux daemon示例,作者宇内流云 * | |
********************************************/ | |
namespace daemon | |
{ | |
class Program | |
{ | |
const string DaemonTag = "--daemon."; | |
static void Main(string[] args) | |
{ | |
// 如果已经是daemon后台服务,就直接执行后台主函数 | |
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(DaemonTag)) == false) | |
{ | |
Environment.SetEnvironmentVariable(DaemonTag, null); | |
DaemonMain(args); | |
return; | |
} | |
// 如果还不是daemon状态,就作daemon处理 | |
/////////////////////////////////////////////// | |
int pid = fork(); | |
if (pid != 0) exit(0); | |
setsid(); | |
pid = fork(); | |
if (pid != 0) exit(0); | |
umask(0); | |
// 这儿已经进入“守护进程”工作状态了! | |
//关闭所有打开的文件描述符 | |
int max = open("/dev/null", 0); | |
for (var i = 0; i <= max; i++) { close(i); } | |
// 设置标记,防止重复运行 | |
Environment.SetEnvironmentVariable(DaemonTag,"yes"); | |
//为execp重组参数 | |
var args1 = args == null ? new string[2] : new string[args.Length + 2]; | |
args1[0] = "mono"; | |
args1[1] = Path.Combine(Environment.CurrentDirectory, Thread.GetDomain().FriendlyName); | |
//复制参数 | |
if (args1.Length > 2) | |
{ | |
for (var i = 0; i < args.Length; i++) | |
{ args1[i + 2] = args[i]; } | |
} | |
//守护状态下重新加载和运行本程序 | |
execvp("mono", args1); | |
} | |
/// <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() { | |
fs = File.Open("/tmp/daemon.txt", FileMode.OpenOrCreate); | |
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment