当前位置:网站首页>【sylar】框架篇-Chapter20-守护进程模块
【sylar】框架篇-Chapter20-守护进程模块
2022-07-28 04:25:00 【江湖人称菠萝包】
站在巨人的肩膀上
概述
- 将进程与终端解绑,转到后台运行(通过 fork 出子进程作为主业务进程的方式实现)。
- sylar 实现了双进程唤醒功能,父进程作为守护进程的同时会检测子进程是否退出,如果子进程退出,则会定时重新拉起子进程。
daemon.h
- ProcessInfo
- 单例模式,存放所需的进程的一些信息。
- start_daemon
- 对外提供的接口。
其他说明
- 以下是守护进程的实现步骤:
- 调用 daemon(1, 0) 将当前进程以守护进程的形式运行;
- 守护进程 fork 子进程,在子进程运行主业务;
- 父进程通过 waitpid() 检测子进程是否退出,如果子进程退出,则重新拉起子进程。
- daemon() 函数
#include <unistd.h> int daemon(int nochdir, int noclose);- 当 nochdir 为0时,daemon 将更改进程的工作目录为根目录 root(“/”)。
- 当 noclose 为0时,daemon 将进程的 STDIN, STDOUT, STDERR 都重定向到 /dev/null,也就是不输出任何信息,否则照样输出。一般情况下,这个参数都是设为0的。
- deamon() 调用了 fork(),如果fork成功,父进程在 daemon 函数运行完毕后自杀,子进程由 init 进程领养。此时的子进程,其实就是守护进程了。
- 一般使用 daemon(1, 0);
部分相关代码
/**
* @filename daemon.h
* @brief 守护进程模块
* @author L-ge
* @version 0.1
* @modify 2022-07-18
*/
#ifndef __SYLAR_DAEMON_H__
#define __SYLAR_DAEMON_H__
#include <unistd.h>
#include <functional>
#include "sylar/singleton.h"
namespace sylar
{
struct ProcessInfo
{
/// 父进程id
pid_t parent_id = 0;
/// 主进程id
pid_t main_id = 0;
/// 父进程启动时间
uint64_t parent_start_time = 0;
/// 主进程启动时间
uint64_t main_start_time = 0;
/// 主进程重启的次数
uint32_t restart_count = 0;
std::string toString() const;
};
typedef sylar::Singleton<ProcessInfo> ProcessInfoMgr;
/**
* @brief 启动程序可以选择用守护进程的方式
* @param[in] argc 参数个数
* @param[in] argv 参数值数组
* @param[in] main_cb 启动函数
* @param[in] is_daemon 是否守护进程的方式
* @return 返回程序的执行结果
*/
int start_daemon(int argc, char** argv
, std::function<int(int argc, char** argv)> main_cb
, bool is_daemon);
}
#endif
#include "daemon.h"
#include "sylar/log.h"
#include "sylar/config.h"
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
namespace sylar
{
static sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("system");
static sylar::ConfigVar<uint32_t>::ptr g_daemon_restart_interval
= sylar::Config::Lookup("daemon.restart_interval", (uint32_t)5, "daemon restart interval");
std::string ProcessInfo::toString() const
{
std::stringstream ss;
ss << "[ProcessInfo parent_id=" << parent_id
<< " main_id=" << main_id
<< " parent_start_time=" << sylar::Time2Str(parent_start_time)
<< " main_start_time=" << sylar::Time2Str(main_start_time)
<< " restart_count=" << restart_count << "]";
return ss.str();
}
static int real_start(int argc, char** argv,
std::function<int(int argc, char** argv)> main_cb)
{
ProcessInfoMgr::GetInstance()->main_id = getpid();
ProcessInfoMgr::GetInstance()->main_start_time = time(0);
return main_cb(argc, argv);
}
static int real_daemon(int argc, char** argv,
std::function<int(int argc, char** argv)> main_cb)
{
// #include <unistd.h>
// int daemon(int nochdir, int noclose);
// 当 nochdir 为0时,daemon 将更改进程的工作目录为根目录root("/")。
// 当noclose为0时,daemon将进程的STDIN, STDOUT, STDERR都重定向到/dev/null,也就是不输出任何信息,否则照样输出。一般情况下,这个参数都是设为0的。
// deamon()调用了fork(),如果fork成功,父进程在daemon函数运行完毕后自杀,子进程由init进程领养。此时的子进程,其实就是守护进程了。
daemon(1, 0); // 创建守护进程
ProcessInfoMgr::GetInstance()->parent_id = getpid();
ProcessInfoMgr::GetInstance()->parent_start_time = time(0);
while(true)
{
pid_t pid = fork();
if(pid == 0)
{
//子进程返回
ProcessInfoMgr::GetInstance()->main_id = getpid();
ProcessInfoMgr::GetInstance()->main_start_time = time(0);
SYLAR_LOG_INFO(g_logger) << "process start pid=" << getpid();
return real_start(argc, argv, main_cb);
}
else if(pid < 0)
{
SYLAR_LOG_ERROR(g_logger) << "fork fail return=" << pid
<< " errno=" << errno << " errstr=" << strerror(errno);
return -1;
}
else
{
//父进程返回
int status = 0;
waitpid(pid, &status, 0);
if(status)
{
if(status == 9)
{
SYLAR_LOG_INFO(g_logger) << "killed";
break;
}
else
{
SYLAR_LOG_ERROR(g_logger) << "child crash pid=" << pid
<< " status=" << status;
}
}
else
{
SYLAR_LOG_INFO(g_logger) << "child finished pid=" << pid;
break;
}
ProcessInfoMgr::GetInstance()->restart_count += 1;
// 防止子进程死掉之后资源还没有被全部回收,
// 此时又马上fork出子进程可能会有问题。
sleep(g_daemon_restart_interval->getValue());
}
}
return 0;
}
int start_daemon(int argc, char** argv
, std::function<int(int argc, char** argv)> main_cb
, bool is_daemon)
{
if(!is_daemon)
{
ProcessInfoMgr::GetInstance()->parent_id = getpid();
ProcessInfoMgr::GetInstance()->parent_start_time = time(0);
return real_start(argc, argv, main_cb);
}
return real_daemon(argc, argv, main_cb);
}
}
广告时间:基于sylar框架实现的小demo(希望给个star)
边栏推荐
- Shell rental reptile
- 【sylar】框架篇-Chapter24-支持业务模块化
- Important SQL server functions - other functions
- 重要的 SQL Server 函数 - 日期函数
- Fedformer MOE module
- Citrix virtual desktop tcp/udp transmission protocol switching
- Information system project manager (2022) - key content: Information System Security Management (20)
- Password key hard coding check
- 将数据库拿到的数据渲染到elementUI 中的table中去
- Go structure
猜你喜欢

10 more advanced open source command line tools

Advanced architects, 16 common principles of microservice design and Governance

《KG-BERT: BERT for Knowledge Graph Completion》

H. 265 web player easyplayer realizes webrtc video real-time recording function

Information system project manager (2022) - key content: Project Portfolio Management (19)

Ma Yi, Shen Xiangyang, Cao Ying's latest AI overview is hot! It took 3 months to build, netizens: required papers

Program life | test engineers only know a little? Seven shortcuts teach you to learn new technology quickly

glusterfs 文件未挂载,权限: r-s

There are so many ways to view the web source code! Do you know?
![[blood vessel detection] Based on MATLAB mom method, combined with Hessian and curve fitting, blood vessel diameter measurement [including Matlab source code, 1970]](/img/72/10bd8a292c3ee3445907795ebf2ae8.png)
[blood vessel detection] Based on MATLAB mom method, combined with Hessian and curve fitting, blood vessel diameter measurement [including Matlab source code, 1970]
随机推荐
Some personal understandings of openpose
23 openwrt switch VLAN configuration
Remove screen cutting and copying restrictions
"Three no's and five requirements" principle of enterprise Digitalization Construction
Un7.27: common commands of redis database.
Idea start project MVN command terminal cannot recognize "MVN" item as cmdlet
There are so many ways to view the web source code! Do you know?
IPC: multi process binder Aidl user guide, including cases
[record of question brushing] 9. Number of palindromes
《KG-BERT: BERT for Knowledge Graph Completion》
[kinematics] simulation of orbital angular momentum based on MATLAB [including Matlab source code 1971]
Go grpc: a solution of connection reset by peer
Important SQL server functions - other functions
Information system project manager (2022) - key content: organization level project management, process management, project set management (18)
【sylar】框架篇-Chapter24-支持业务模块化
Kingbasees Security Guide for Jincang database -- 5.2. data integrity protection
Difference between on, where and having
重要的 SQL Server 函数 - 其他函数
About me writing a custom cell
【实战】使用 Web Animations API 实现一个精确计时的时钟