Linux下Daemon进程示例。
将进程ID写入到文件中,并对文件加锁,确保只有一个daemon进程在运行。此外,有信号处理函数示例。
(备注:参考大名鼎鼎的 APUE中示例,整理而出 :))
#include <iostream> using namespace std; //TO BE ADDED #include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #define PIDFILE "main.pid" int Lockfile(const int iFd) { struct flock stLock; stLock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ stLock.l_start = 0; /* byte offset, relative to l_whence */ stLock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ stLock.l_len = 0; /* #bytes (0 means to EOF) */ return (fcntl(iFd, F_SETLK, &stLock)); } int IsRunning() { const int iPidFile = open(PIDFILE, O_RDWR | O_CREAT, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); if (iPidFile < 0) { cout << "Can not open pid file:" << PIDFILE << endl; return -1; } //lock file if (Lockfile(iPidFile) < 0) { if ((EACCES == errno) || (EAGAIN == errno)) { close(iPidFile); cout << "Is already running" << endl; return 1; //already running } //fail to lock cout << "Cant lock pid file:" << PIDFILE << endl; return -1; } //write pid ftruncate(iPidFile, 0); char buf[16]; sprintf(buf, "%ld", (long)getpid()); write(iPidFile, buf, strlen(buf) + 1); return 0; } int SetDaemon() { //umask(0); int iPid = 0; if ((iPid = fork()) < 0) { //fork error return -1; } else if (0 != iPid) //parent { exit(0); } //setsid(); return 0; } void SigTerm(int iSig) { cout << "Recv single term," << iSig << endl; } void SigHup(int iSig) { cout << "Recv single hup," << iSig << endl; } void SigUsr1(int iSig) { cout << "Recv single Usr1," << iSig << endl; } int HandleSingle() { struct sigaction stSigAct; stSigAct.sa_handler = SigTerm; sigemptyset(&stSigAct.sa_mask); sigaddset(&stSigAct.sa_mask, SIGTERM); stSigAct.sa_flags = 0; if (sigaction(SIGTERM, &stSigAct, NULL) < 0) { cout << "Can not catch SIGTERM," << strerror(errno) << endl; return -1; } stSigAct.sa_handler = SigHup; sigemptyset(&stSigAct.sa_mask); sigaddset(&stSigAct.sa_mask, SIGHUP); stSigAct.sa_flags = 0; if (sigaction(SIGHUP, &stSigAct, NULL) < 0) { cout << "Can not catch SIGHUP," << strerror(errno) << endl; return -1; } stSigAct.sa_handler = SigUsr1; sigemptyset(&stSigAct.sa_mask); sigaddset(&stSigAct.sa_mask, SIGUSR1); stSigAct.sa_flags = 0; if (sigaction(SIGUSR1, &stSigAct, NULL) < 0) { cout << "Can not catch SIGUSR1," << strerror(errno) << endl; return -1; } return 0; } int main() { int iRet = 0; iRet = SetDaemon(); if (0 != iRet) { cout << "Fail to set daemon, now exit." << endl; exit(0); } iRet = IsRunning(); if (0 != iRet) { cout << "Is running!" << endl; exit(1); } cout << "\nmain daemon running..." << endl; iRet = HandleSingle(); if (iRet < 0) { cout << "HandleSingle error" << endl; exit(1); } while (1) { pause(); //wait for signal } //sleep(60); //sleeping 60s //pause() causes the calling process (or thread) to sleep until a signal is delivered // that either terminates the process or causes the invocation of // a signal-catching function. //sleep() makes the calling thread sleep until seconds seconds have elapsed or a //signal arrives which is not ignored. return 0; }