当前位置: 首页 > news >正文

永久免费的建站系统有哪些建筑公司网站首页

永久免费的建站系统有哪些,建筑公司网站首页,备案的网站名称能重复备案吗,广告公司创意取名Linux系统编程 - 进程异常自动重启 文章目录 Linux系统编程 - 进程异常自动重启开篇基础概念守护进程僵死进程(zombie) 设计思路源码实现总结 开篇 在Linux平台#xff0c;自研服务进程通常以守护进程的形式在后台常驻运行。但偶尔也会遇到服务进程异常crash#xff0c;导致产…Linux系统编程 - 进程异常自动重启 文章目录 Linux系统编程 - 进程异常自动重启开篇基础概念守护进程僵死进程(zombie) 设计思路源码实现总结 开篇 在Linux平台自研服务进程通常以守护进程的形式在后台常驻运行。但偶尔也会遇到服务进程异常crash导致产品基本功能异常影响恶劣。   解决这种问题通常两种应对措施   ① 定位crash原因上传补救措施。   ② 后台重新拉起异常进程避免影响基本功能。 对于措施①系统部署coredump文件通过gdb解析coredump文件就能很快定位到原因本篇主要记录下措施②实现流程。 基础概念 守护进程 守护进程(daemon)是一类在后台运行的特殊进程用于执行特定的系统任务。很多守护进程在系统引导的时候启动并且一直运行直到系统关闭。另一些只在需要的时候才启动完成任务后就自动结束。   守护进程的特点是不占用终端后台运行。在终端只需要在启动进程时加即可启动一个守护进程: $ ./testBin 僵死进程(zombie) long long ago子进程终止后会在系统中完全消失父进程无从查询子进程的信息。因此UNIX设计者们作出一个这样的约定如果一个子进程在父进程之前结束内核应该把子进程设置为一个特殊的状态。处于这种状态的进程叫做僵死(zombie)进程。僵死进程只保留一些最小的概要信息直至父进程获取这些信息才会完全消失否则一直保持僵死状态。父进程可通过wait()/waitpid()获取这些状态。   如果父进程先退出子进程被init接管子进程退出后init会回收其占用的相关资源。通过终端查看僵死进程(后缀带有defunct) $ ps -ef | grep defunct dx 10144 10135 0 18:08 pts/2 00:00:00 [test] defunct设计思路 通过对僵死进程概念的理解子进程先于父进程结束时会在系统产生一个僵死进程直至父进程对其回收。则可以通过这点实现进程异常crash的重启。 方案一   在《Linux系统编程》中有讲道当子进程终止时会发送SIGCHLD至父进程。因此可按如下流程 父进程先创建一个子进程在子进程中通过execl拉起需要的bin。此时父进程缓存bin文件对应路径和对应的pid。父进程注册信号SIGCHLD监听在处理函数中通过wait()/waitpid()获取异常子进程的pid。通过pid匹配异常进程对应的bin文件路径再重新拉起此进程。 方案二   进程在启动时都会在/proc下创建一个对应的目录/proc/[pid]/。可通过监测此路径实现流程如下 同方案一。获取到子进程的pid后父进程一直检测/proc/[pid]是否存在不存在时重新拉起进程。 方案三   由于waitpid()可以获取所有僵死子进程的pid因此通过轮询此接口可实现流程如下 同方案一通过waitpid()可获取所有僵死子进程的匹配对应bin路径重新拉起。 其中方案一是触发式监测属于其中最优雅的方法。但是在实测过程中发现子进程异常终止时父进程存在小概率收到不到信号SIGCHLD网上的说法是SIGCHLD不可靠。从而导致监测子进程状态失败因此将终端触发改为轮询衍生了方案三。   方案二也是可行的网上很多也是这么做的。既然有waitpid接口个人更倾向于方案三。 源码实现 代码同时实现了方案一和方案三用CONFIG_SUPPORT_SIGCHLD控制。为1时为方案一实现为0时为方案三实现实测方案一SIGCHLD偶尔接收不到。 #define CONFIG_SUPPORT_SIGCHLD 0 // SIGCHLD不可靠。 1: 信号中断 0: 轮询#define LOG(fmt, args...) printf(fmt, ##args) #define LOGD(fmt, args...) printf([%d] %-20s %-4d D: fmt, getpid(), __FUNCTION__, __LINE__, ##args) #define LOGE(fmt, args...) printf([%d] %-20s %-4d E: fmt, getpid(), __FUNCTION__,__LINE__, ##args)typedef struct exeInfo {char path[20];int times; } SExeInfo;typedef std::mapint, shared_ptrSExeInfo TMapPid2Path;const char PROC_PATH[] /proc; TMapPid2Path pidMap;static std::mutex sigchildMtx; static std::condition_variable sigchildCond;static bool existExeByProc(int pid) {struct stat fileStat;char pidPath[20] {0};snprintf(pidPath, sizeof(pidPath), %s/%d, PROC_PATH, pid);int ret lstat(pidPath, fileStat);if (ret) {//LOGD(%s lstat failed. errno %d (%s)\n, pidPath, errno, strerror(errno));return false;}// /proc/pid/ 为目录则当前进程正常if (S_ISDIR(fileStat.st_mode)) {return true;}return false; }static void dumpPidMapInfo(const TMapPid2Path aMap) {LOGD(PID PATH TIME\n);LOGD(----------------------------------\n);for (auto it aMap.begin(); it ! aMap.end(); it) {LOGD(%-6d %-20s %-2d \n, it-first, it-second-path, it-second-times);}LOGD(----------------------------------\n); }static void startExe(const char *pExePath) {static int pid -1;pid fork();if (pid -1) {LOGE(fork failed. errno %d (%s).\n, errno, strerror(errno));} else if (pid 0) { // 子进程static int startCount 0;LOGD(Pull up %s (%d).\n, pExePath, startCount);execl(pExePath, pExePath);} else { // 父进程LOGD(Child fork pid: %d.\n, pid);auto it pidMap.begin();for (; it ! pidMap.end(); it) {if (!strncmp(it-second-path, pExePath, strlen(pExePath))) {LOG(find %s %s.\n, it-second-path, pExePath);break;}}if (it pidMap.end()) {shared_ptrSExeInfo spInfo make_sharedSExeInfo();strncpy(spInfo-path, pExePath, sizeof(spInfo-path));spInfo-times 1;pidMap.insert(pairint, shared_ptrSExeInfo(pid, spInfo));} else {it-second-times;pidMap.insert(pairint, shared_ptrSExeInfo(pid, it-second));pidMap.erase(it);}} }#if CONFIG_SUPPORT_SIGCHLD static bool sigchildRcv false; static void handler(int sig, siginfo_t *si, void *unused) {LOGD(Receive sig: %d.\n, sig);sigchildRcv true;sigchildCond.notify_one(); } #endif// Eg. ./exe /tmp/test_bin int main(int argc, char *argv[]) {if (argc 2) {LOGE(usage: %s [path].\n, argv[0]);return 0;}#if CONFIG_SUPPORT_SIGCHLDstruct sigaction sa;sigemptyset(sa.sa_mask);sa.sa_sigaction handler;if (sigaction(SIGCHLD, sa, NULL) -1){LOGE(sigaction failed! errno %d (%s) \n, errno, strerror(errno));} #endiffor (int i 1; i argc; i) {startExe(argv[i]);}thread th1([]() {while(1) {#if !(CONFIG_SUPPORT_SIGCHLD)int pid 0, status 0;while( (pid waitpid(-1, status, WNOHANG)) 0) {if (!existExeByProc(pid) pidMap.count(pid)) {startExe(pidMap[pid]-path);}} #elsestd::unique_lockstd::mutex lk(sigchildMtx);sigchildRcv false;sigchildCond.wait(lk, []{int pid 0, status 0;while( (pid waitpid(-1, status, WNOHANG)) 0) {if (!existExeByProc(pid) pidMap.count(pid)) {startExe(pidMap[pid]-path);}}LOGD(Receive SIGCHLD.\n);return sigchildRcv;});lk.unlock(); #endifdumpPidMapInfo(pidMap);sleep(1);}});th1.join();return 0; }测试 实验bin /tmp/test为2s crash的bin文件tmp/lambda正常运行bin。 预期: test进程2s挂掉会被自动拉起lambda进程正常运行不受影响。 $ ./exe /tmp/test /tmp/lambda [12737] startExe 99 D: Child fork pid: 12738. [12737] startExe 99 D: Child fork pid: 12739. [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12738 /tmp/test 1 [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12738] startExe 96 D: Pull up /tmp/test (1). [12739] startExe 96 D: Pull up /tmp/lambda (1). [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12738 /tmp/test 1 [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12738 /tmp/test 1 [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12737] startExe 99 D: Child fork pid: 12742. find /tmp/test /tmp/test. [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 81 D: 12742 /tmp/test 2 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12742] startExe 96 D: Pull up /tmp/test (1). [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 81 D: 12742 /tmp/test 2 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 81 D: 12742 /tmp/test 2 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12737] startExe 99 D: Child fork pid: 12744. find /tmp/test /tmp/test. [12737] dumpPidMapInfo 78 D: PID PATH TIME [12737] dumpPidMapInfo 79 D: ---------------------------------- [12737] dumpPidMapInfo 81 D: 12739 /tmp/lambda 1 [12737] dumpPidMapInfo 81 D: 12744 /tmp/test 3 [12737] dumpPidMapInfo 83 D: ---------------------------------- [12744] startExe 96 D: Pull up /tmp/test (1).总结 在开发阶段应优先查后台进程异常终止的原因。通常由系统配置生成coredump文件配合gdb可以快速定位到crash代码行号。至于方案一偶尔收不到SIGCHLD缩短处理函数的响应时间排除信号处理函数不可重入因素还是存在问题。网上查到的原因此信号不可靠具体原因尚不清晰。经过此方案在Linux系统部署用户进程时加入此方案能够避免进程异常导致的系统宕机等其他严重问题。
http://www.pierceye.com/news/827604/

相关文章:

  • 深圳建设高端网站asp.net 获取网站的绝对路径
  • 做的网站没流量吗前端页面设计
  • 门户网站的优点在环评备案网站上做登记后会怎么样
  • 网站的内容规划怎么写网站做外链的具体步骤
  • 百度网站排名规则小程序网站建设y021
  • 中国建设银行国际互联网站国内排名前五的电商
  • 怎么查网站的空间商四川建设工程招标网
  • 网站建设比较好公司朝阳区互联网公司排名
  • 百度不收录网站吗网站开发php
  • 房产网站建设的功能wordpress php7拓展
  • 做网站代码用什么软件天津建设工程信息网天津
  • 网站开发工程师前景怎么样怎么做自己的网站?
  • 井陉矿区网站建设做微商的网站
  • 办公室装修专业网站小程序免费制作平台有吗
  • 学生做兼职去哪个网站线上推广的渠道有哪些
  • 徐州网站的优化苏州百度推广开户
  • 网站有多少个网站建设与管理介绍
  • 网站建站报告2000字查询公司的网站
  • 兰州网站制作服务电话博客建站模板
  • 网站后台登陆路径网站网站优化
  • wordpress仿站方法网站图片做伪静态
  • 怎么做一款贷款网站蚌埠seo公司
  • 做羊水亲子鉴定网站企业vi设计公司定制
  • 网站开发和微信开发需要什么人一个服务器放多少网站
  • 做6个页面的网站郑州seo优化顾问热狗
  • 网站建设 落地页中国石化工程建设有限公司怎么样
  • 网站建设 软文发布wordpress调取列表页
  • php网站服务器架设清远哪里有网页设计培训学费
  • 建站开发搜索引擎排名查询
  • 如何建设自己的网站 知乎怎么做电力设计公司网站