Linux 下的一个进程打开一个日志文件,不定期地往该文件里写入日志。此时可以在控制台使用 mv 命令给该日志文件改个名字或者用 rm 命令把这个日志文件删除掉。Linux 下是允许这么干的!对于改日志文件名的情形还好一点,后续的日志还是会写入更名后的文件里,只是会影响后面日志文件自动清理功能(比如把日志文件名改得像个进程文件名);而对于删除文件的情形,就直接导致后续的日志无法计入日志文件,一直到第二天凌晨日志文件切换时才回复正常。

为此,增加了一个日志文件保护功能,放在一个独立的线程 logGuardEntry 里运行。这个保护功能主要是定期检查当前所使用的日志文件是否存在,以及日志记录是否正常,若检测到异常,则关闭当前日志输出的文件句柄,并重新打开所使用的文件,文件不存在则重建。

用 debug 版调试运行,功能正常后生成 release 版,却测试发现增加的日志文件保护功能没有起作用。用 gdb 挂上进程查看线程栈,想看下 logGuardEntry 线程内部出了什么状况,结果发现根本就没有 logGuardEntry 这个线程!

仔细排查,才发现问题和 daemonInit 函数调用有关系。main 函数里相关调用示意如下:

int main()
{
...
startLogWriter(...);
...
#ifndef _DEBUG
daemonInit();
#endif
...
}

startLogWriter 函数体末尾有一行:

startThread(logGuradEntry,...);

即启动一个以 logGuardEntry 为入口函数的线程,实施日志文件保护的功能。

daemonInit 函数里有如下代码段:

void daemonInit()
{
...
pid = fork();
if (pid != 0) {
exit(0);
}
...
}

这是让程序以守护进程运行的通常做法,即让主进程退出,而让子进程经过进一步处理成为守护进程继续运行。但是 fork 调用生成的子进程在 fork() 这条语句完成时,只会有一个线程,即调用 fork 的线程(上面就是 main 所在的线程,即主线程)。这是 Linux 出于某种合理的考虑而这样设计的。上面的 main 函数里,先调用了 startLogWriter,里面会启动一个 logGuard 线程,这时主进程有两个线程在运行;而随后调用 daemonInit,导致主进程退出,而子进程却丢掉了 logGuard 线程,导致测试时发现日志保护功能根本不起作用。

当然,这个问题改起来很简单,把 startLogWriter 调用放到 daemonInit 之后就好了,即:

int main()
{
...
#ifndef _DEBUG
daemonInit();
#endif
startLogWriter
(...);
...
}

就是说,对于以守护进程运行的后台程序而言,daemonInit 调用尽量早一些做,尤其不要在调用 daemonInit 之前启动工作线程。

由 fork 调用的工作机制,不禁会想:子进程是不是可以没有 main() 函数所在的线程,即所谓主线程(比如,把上面的 daemonInit 调用挪到 logGuard 线程里调用)?

实际试验了一下,果然是可以的。以下是用 gdb 挂上进程看到的内情:

一个 Linux 后台程序编程案例分析的更多相关文章

  1. 如何在终端使用后台运行模式启动一个Linux应用程序

    这是一个篇幅不长但是十分有用的教程,可以帮助你在终端启动一个Linux应用程序,并且使终端窗口不会丢失焦点. 我们有很多可以在Linux系统中打开一个终端窗口的方法,这取决于你的选择以及你的桌面环境. ...

  2. 第六章第一个linux个程序:统计单词个数

    第六章第一个linux个程序:统计单词个数 从本章就开始激动人心的时刻——实战,去慢慢揭开linux神秘的面纱.本章的实例是统计一片文章或者一段文字中的单词个数.  第 1 步:建立 Linu x 驱 ...

  3. Linux网络编程案例分析

    本代码来自于博主:辉夜星辰 本篇主要对运行代码中出现的问题进行分析,代码本身的内容后续展开讨论. 服务器端代码 /* Linux网络编程之TCP编程,服务器端读数据 socket函数之后,返回值ser ...

  4. Linux SSH登录慢案例分析

    手头有台Linux服务器ssh登录时超级慢,需要几十秒.其它服务器均没有这个问题.平时登录操作都默默忍了.今天终于忍不住想搞清楚到底什么原因.搜索了一下发现了很多关于ssh登录慢的资料,于是自己也学着 ...

  5. Linux input子系统编程、分析与模板

    输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系 ...

  6. 多线程学习-基础( 十)一个synchronized(){/*代码块*/}简单案例分析

    一.提出疑惑 上一篇文章中,分析了synchronized关键字的用法.但是好像遗漏了一种情况. 那就是: synchronized(obj){/*同步块代码*/} 一般有以下几种情况: (1)syn ...

  7. Linux服务器挂死案例分析

    问题现象: 在linux服务器上运行一个指定的脚本时,就会出现无数个相同进程的,而且不停的产生,杀也杀不掉,最后系统就陷入死循环,无法登陆,只能人工去按机器的电源键才可以.这够崩溃的吧? 问题分析过程 ...

  8. 作为一个Linux/Unix程序员有哪些要求

    C程序开发: 熟悉数据库sql语言: 熟练掌握C语言(面向过程的),掌握C++(面向对象的) 工程管理工具:make,会写Makefile 熟悉IBM DB2.Informix.Sysbase.SQL ...

  9. Linux 应用程序编程基础

    一个计算机应用程序在内存中可以分成两个部分:存放代码的代码段和存放数据的数据段.代码段存放用户编写的代码;数据段存放栈和堆. 相关内存管理函数 #include <stdlib.h> vo ...

随机推荐

  1. 【UE4】虚幻引擎技术直播汇总(含中英文直播)

    B站虚幻引擎官方账号 中文直播 [中文直播]第35期 | 使用GIS在UE中创造真实地球风貌 | Epic 周澄清 [中文直播]第34期 | 包教包会的Epic MegaGrants申请之道 | Ep ...

  2. 在 Windows 10 上安装 Coq 库 Mathematical Components

    初学 Coq 时看的是 Mathematical Components 这本书,它自带了一个 Coq 的库,这是它的安装教程 这个库的安装要用到 OCaml Package Manager (OPAM ...

  3. Java中的函数式编程(八)流Stream并行编程

    写在前面 在本系列文章的第一篇,我们提到了函数式编程的优点之一是"易于并发编程". Java作为一个多线程的语言,它通过 Stream 来提供了并发编程的便利性. 题外话: 严格来 ...

  4. MD支持程度测试

    Editor.md 目录 (Table of Contents) [TOCM] 目录 Editor.md Heading 1 Heading 2 Heading 3 Heading 4 Heading ...

  5. 21.6.29 test

    \(NOI\) 模拟赛 \(T1\) 正解是个题解难以理解的数论,结果是组合数相加.暴力分拿满了,尝试打了 \(20*20\) 的表,最后大概打出了个三角形的表,并且帮我找到了一些性质.\(45\)p ...

  6. SpringCloud微服务实战——搭建企业级开发框架(十五):集成Sentinel高可用流量管理框架【熔断降级】

      Sentinel除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一.由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积.Sentinel ...

  7. 13.G1垃圾收集器

    G1收集器是一款面向服务器的垃圾收集器,也是HotSpot在JVM上力推的垃圾收集器,并赋予取代CMS的使命.为什么对G1收集器给予如此高的期望呢?既然对G1收集器寄予了如此高的期望,那么他一定是有其 ...

  8. Code Runner for VS Code,下载量突破 3000 万!

    还记得五年前的夏天,我在巨硬写着世界上最好的语言,有时也需要带着游标卡尺写着另一门语言.然而,我对这两门语言都不熟悉,如果能在 VS Code 中方便快捷地运行各种语言,那岂不是很方便?于是,我就开发 ...

  9. Java测试开发--MySql之C3P0连接池(八)

    连接池C3P0! 连接池技术的目的:解决建立数据库连接耗费资源和时间很多的问题,提高性能 ! 下面以案例演示下C3P0的操作流程. 1.测试准备: ①MySql数据库一枚②database名为myte ...

  10. LoadRunner12浏览器录制(谷歌火狐)

    一.使用谷歌浏览器 下载的版本 65.0.3325.162(正式版本)(64 位)安装之前要记得把电脑现有的谷歌浏览器卸载了. 1.下载地址:https://www.chromedownloads.n ...