CentOS下的Daemon进程

来源:互联网 发布:mac os x 10.6.8 编辑:程序博客网 时间:2024/04/30 22:46
Date:2016-03-03
Author:kagula


Environment:

[1]CentOS7
[2]Win10
[3]Visual Studio 2013 Update5
[4]gcc 4.8.5


Prologue:

  经我几次测试,baidu上说的普通进程的缺陷我还是看不出来
比如说:
[1]普通进程也可以后台运行,不受终端影响。终端退出后它还是存在的。
[2]普通进程在kill后,也能catch到信号,做正常退出动作,然后再调用Exit退出。


但是为了避免未知的问题还是改了代码,把它弄成Daemon进程。
这里记下示例代码,免得时间长忘记了。
主要有FakeServer.cpp、SourceLinux.cpp、utility.cpp三个文件组成,

“Daemon process”的重点是在SourceLinux.cpp中。


弄个假的服务程序段

FakeServer.cpp
#include "FakeServer.h"extern bool g_bTerm;void  fakeServer(){while (1){if (g_bTerm){break;}}}



在CentOS下启动Daemon process的代码

SourceLinux.cpp
#ifndef WIN32#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <syslog.h>#include <string.h>#include <signal.h>#include "FakeServer.h"#include "utility.h"//the var may need thread protection.//g_bTerm用于通知服务器是否结束程序.bool g_bTerm = false;//通知我们的服务器代码,可以结束服务了。。。void signal_term_handler(int signal_num){g_bTerm = true;kagula::g_log.info("signal_term_handler work!");}int main(int argc, char* argv){pid_t pid, sid;/* Fork off the parent process */pid = fork();if (pid < 0) {exit(EXIT_FAILURE);}/* If we got a good PID, then we can exit the parent process. */if (pid > 0) {exit(EXIT_SUCCESS);}//产生的子进程将变成孤儿进程,并被init进程接管.//同时,所产生的新进程将变为在后台运行./* Create a new SID for the child process *///setsid函数将创建新的会话,并使得调用setsid函数的进程成为新会话的领头进程.//会话的领头进程没有控制终端与其相连。满足了守护进程没有控制终端的要求.sid = setsid();if (sid < 0) {/* Log any failure here */exit(EXIT_FAILURE);}/* Change the current working directory */if ((chdir("/")) < 0) {/* Log any failure here */exit(EXIT_FAILURE);}//赋予当前进程最大文件读写权限.umask(0);/* Close out the standard file descriptors *///Daemon Process不能使用终端,这些文件描述符就是多余//所以关闭他们close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);//kagula::InitLog();kagula::g_log.info("Initialization log module.");//检查进程的数量,如果大于等于2说明已经启动了两个进程.//那就退出当前进程.if (kagula::NumberOfProcess()>=2){kagula::g_log.error("Already running...");return -1;}//处理Kill <pid>发出的信号,并进行退出处理。signal(SIGTERM,signal_term_handler);//启动我们(假)的服务程序.fakeServer();//释放“用于判断当前进程数量的”共享内存。kagula::ReleaseKagula();//退出exit(EXIT_SUCCESS);return 0;}#endif



编译上面的代码所需要的支撑文件

utility.h
#ifndef _UTILITY_H_#define _UTILITY_H_#include "simpleLog.h"namespace kagula{void InitLog();extern simpleLogClass g_log;int NumberOfProcess();bool ReleaseKagula();}#endif



utility.cpp

#include "utility.h"#include <boost/interprocess/shared_memory_object.hpp> #include <boost/interprocess/mapped_region.hpp> namespace kagula{simpleLogClass g_log;void InitLog(){g_log.fileMaxSize = 64 * 1024;#ifdef WIN32g_log.fileName = "processname.log";g_log.fileOldName = "processname.log";#elseg_log.fileName = "/var/log/kagula/processname.log";g_log.fileOldName = "/var/log/kagula/processname.log";#endif}#define SHARED_MEMORY_OBJECT_NAME "TestCentOSDaemonProcess"int NumberOfProcess(){boost::interprocess::shared_memory_object shdmem(boost::interprocess::open_or_create, SHARED_MEMORY_OBJECT_NAME, boost::interprocess::read_write);shdmem.truncate(8);//shdmem.truncate(1024);//设定共享内存大小boost::interprocess::mapped_region region(shdmem, boost::interprocess::read_write);int *i1 = static_cast<int*>(region.get_address());(*i1) += 1;return (*i1);}bool ReleaseKagula(){return boost::interprocess::shared_memory_object::remove(SHARED_MEMORY_OBJECT_NAME);}}


CMakeLists.txt

project(TestCentOSDaemonProcess) cmake_minimum_required(VERSION 2.8)  SET( CMAKE_VERBOSE_MAKEFILE ON )  find_package(Boost 1.57 COMPONENTS system filesystem thread date_time REQUIRED)include_directories(${Boost_INCLUDE_DIRS}) LINK_DIRECTORIES(/usr/local/lib)  aux_source_directory(. DIR_SRCS)  #undefined reference to `boost::system::system_category()#自己在c++命令行上加入-lboost_system,手动在执行c++成功#For boost Interprocess library in CentOS7#-lboost_date_time -lrtadd_executable(TestCentOSDaemonProcess ${Boost_LIBRARIES} ${DIR_SRCS})



常见问题

xxx.so文件找不到
添加库文件search path
vi /etc/ld.so.conf  
#在最后一样添加“/usr/local/lib”
#使路径生效
/sbin/ldconfig -v  
#现在程序可以运行了


查看Daemon进程

TestCentOSDaemonProcess是Daemon进程文件名称

ps -ef|grep TestCentOSDaemonProcess


Reference

[1]《CentOS 7.x设置自定义开机启动,添加自定义系统服务》
http://www.centoscn.com/CentOS/config/2015/0507/5374.html
[2]《centos7 开机/etc/rc.local 不执行的问题》
[3]《Linux下系统日志的使用》
http://blog.chinaunix.net/uid-26983585-id-3322977.html
[3]《signal() 函数详解》
http://blog.sina.com.cn/s/blog_8184e03301013ddz.html
0 0