网络编程套接字(4):日志和守护进程

news2024/10/6 20:25:24

文章目录

  • 网络编程套接字(4): 日志和守护进程
    • 5. 增加日志功能
    • 6. 守护进程
      • 6.1 进程知识补充
        • (1) 进程组
        • (2) 任务
        • (3) 会话
      • 6.2 守护进程
        • (1) 概念
        • (2) 创建守护进程

网络编程套接字(4): 日志和守护进程

5. 增加日志功能

接着上篇的内容,增加日志功能可以更好地,更高效地帮助我们发现在网络通信中遇到的问题

日志分为5个等级

enum 
{
    Debug=0,
    Info,
    Warning,
    Error,
    Fatal,
    Uknown
};

log.hpp

#include<iostream>
#include<string>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<cstdarg>
#include<time.h>
using namespace std;

// 日志系统是有等级的

enum 
{
    Debug=0,
    Info,
    Warning,
    Error,
    Fatal,
    Uknown
};

static string toLevelString(int level)
{
    switch (level)
    {
    case Debug:
        return "Debug";
    case Info:
        return "Info";
    case Warning:
        return "Warning";
    case Error:
        return "Error";
    case Fatal:
        return "Fatal";
    default:
        return "Uknown";
    }
}

string getTime()
{
    time_t curr=time(nullptr);
    struct tm*tmp=localtime(&curr);
    char buffer[128];
    snprintf(buffer,sizeof(buffer),"%d-%d-%d %d:%d:%d",tmp->tm_year+1900,tmp->tm_mon+1,tmp->tm_mday,
            tmp->tm_hour,tmp->tm_min,tmp->tm_sec);
    return buffer;
}

// 日志格式: 日志等级 时间 pid 消息体
// logLeft:  日志等级 时间 pid        logRight:  消息体
// logMessage(Debug, "hello: %d, %s",12,s.c_str())   Debug, hello: 12, world

void logMessage(int level, const char*format,...)
{
    char logLeft[1024];
    string level_string=toLevelString(level);
    string curr_time=getTime();
    snprintf(logLeft,sizeof(logLeft),"[%s] [%s] [%d] ",level_string.c_str(), 	                      curr_time.c_str(),getpid());

    char logRight[1024];
    va_list p;
    va_start(p,format);
    vsnprintf(logRight,sizeof(logRight),format,p);
    va_end(p);

    printf("%s%s\n",logLeft,logRight);
}

关于给服务端添加日志打印我这里就不给出了,放到我的码云:lesson35/log_v1/tcpServer.hpp · 遇健/Linux - 码云 - 开源中国 (gitee.com)

添加成功后运行结果:

在这里插入图片描述

6. 守护进程

6.1 进程知识补充

在这里插入图片描述

(1) 进程组

  • 进程组就是一个或多个进程的集合,每个进程除了有一个PID外,还属于一个进程组。

  • 每一个进程组,都有一个唯一的标识PGID,属于同一个进程组的进程其PGID相同。

  • 进程组中的第一个进程作为组长进程,将其PID作为进程组的PGID

如下,我们同时启动了3个后台进程,它们属于同一进程组,进程组中的第一个进程PID=14378的进程作为组长进程

在这里插入图片描述

(2) 任务

启动一个进程就是启动一个任务

  • 前台任务:通过终端启动,并且在启动后一直占据终端

  • 后台任务:启动时与终端无关,或者通过终端启动后转入后台运行(即释放终端),不影响用户继续在终端中工作

在我们每次登录XShell后,bash会默认占据前台任务,也就是命令行解释器shell(即占用终端的控制权)

当把进程任务自动切换为前台任务时,shell自动切换为后台任务,我们输入的命令就无效了

任务管理命令(Shell中控制进程组的方式):

  • jobs:查看所有任务

在这里插入图片描述

  • fg:把任务提到前台

此时这个任务就会变成前台任务,shell自动切换为后台任务,命令行解释器失效

在这里插入图片描述

  • ctrl+z:暂停前台任务

在这里插入图片描述

  • bg:让暂停的任务在后台继续运行

在这里插入图片描述

(3) 会话

Linux是多用户多任务的分时系统,所以必须要支持多个用户同时使用一个操作系统。当一个用户登录一次系统就形成一次会话。在一个会话中,用户可以与系统进行交互,执行命令、操作文件、启动程序等。

比如,我们先启动3个后台进程,在启动3个前台进程,后获取这些进程的信息

在这里插入图片描述

  • 这些进程分别属于2个进程组,它们与同一个终端关联,属于同一个会话

在这里插入图片描述

  • 启动进程就是启动任务,在每一次登录系统会为我们创建一次会话,会话里至少有bash任务进行命令行解释

  • 命令行里可以启动多个任务,每个任务最终以进程组的形式在会话里存在。

  • 所以一个会话里可能存在很多进程组

  • 大小概念:会话 >= 进程组 >= 进程

6.2 守护进程

(1) 概念

上面的知识概念总结:

  • 进程组分为:前台任务和后台任务

  • 如果把后台任务提到前台,则老的前台任务无法运行

  • 在会话中只能有一个前台任务在运行,所以当我们在命令行启动一个进程的时候,bash就无法运行了

  • 如果登录就是创建一个会话,bash任务启动我们的进程就是在当前会话中创建新的前后台任务,那么我们如果退出呢?就会销毁会话,可能会影响会话内部的所有任务!

我们之前的服务器都是这样的:

每一个服务端进程组与bash进程组同属于一个会话,再次登录Xshell启动服务端就会创建新的会话

在这里插入图片描述

可是一般的网络服务器,为了不受到用户的登录注销的影响,就必须让服务端自成进程组,自成会话,使其与终端的状态无关,可以一直运行的进程,这样的进程就称作守护进程

在这里插入图片描述

(2) 创建守护进程

我们用的setsid函数自己实现守护进程,不使用linux自带生成守护进程的接口daemon

在这里插入图片描述

creates a session and sets the process group ID: 创建会话并设置进程组ID

这个函数的使用关键:调用的进程不能是组长进程

守护进程的创建步骤:

  1. 让调用进程忽略掉异常信号
  2. fork()创建子进程,让父进程直接退出,自己不再是组长进程
  3. 调用setsid,新建会话, 子进程自成进程组,成为会话的首进程
  4. 将标准输入、输出和错误重定向到/dev/null中
  5. 调用close关闭文件描述符,防止守护进程与终端或其他进程的关联
  6. 调用setsid,新建会话, 自己成为会话的首进程

dev/null是linux下的特殊文件,会对写入的内容进行丢弃,通常被用作丢弃不需要的输出或测试程序在遇到写入错误时的行为。

在这里插入图片描述

daemon.hpp

#pragma once

#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "log.hpp"
#include "err.hpp"

// 1. setsid();
// 2. setsid(), 调用进程,不能是组长! 我们怎么保证自己不是组长呢?
// 3. 守护进程, 忽略异常信号 b. 0, 1, 2要特殊处理 c. 进程的工作路径可能要更改

// 守护进程的本质: 是孤儿进程的一种
void Daemon()
{
    // 1. 忽略信号
    signal(SIGPIPE,SIG_IGN);
    signal(SIGCHLD,SIG_IGN);

    // 2. 让自己不要成为组长
    if(fork()>0)      // 父进程直接退出
        exit(0);

    // 3. 新建会话, 自己成为会话的首进程
    pid_t ret=setsid();
    if((int)ret==-1)
    {
        logMessage(Fatal,"deamon error, code: %d, error string: %s",errno,                                  strerror(errno));
        exit(SET_ERR);
    }

    // 4. 可选: 可以更改守护进程的工作路径
    // chdir("/");

    // 5. 处理后续对于0,1,2的问题  --- /dev/null 文件就像垃圾桶
    int fd=open("/dev/null",O_RDWR);  
    if(fd<0)
    {
        logMessage(Fatal,"open error, code: %d, error string: %s",errno,strerror(errno));
        exit(SET_ERR);
    }

    dup2(fd,0);
    dup2(fd,1);
    dup2(fd,2);
    close(fd);
}

给服务端加上该代码

在这里插入图片描述

运行结果:

在这里插入图片描述

  • ?表示该进程与终端无关,我们已经让此服务端以守护进程的方式运行

  • 该进程的PPID为1,说明OS领养了守护进程,守护进程本质是孤儿进程的一种

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/949828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

16.WebSocket聊天室

基于SpringBoot 2.6.11 1.WebSocket WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议&#xff0c;可以在html页面直接使用。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在 WebSocket A…

2021年12月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;书架 John最近买了一个书架用来存放奶牛养殖书籍&#xff0c;但书架很快被存满了&#xff0c;只剩最顶层有空余。 John共有N头奶牛(1 ≤ N ≤ 20,000)&#xff0c;每头奶牛有自己的高度Hi(1 ≤ Hi ≤ 10,000)&#xff0c;N头奶牛的总高度为S。书架高度为B(1 ≤…

亚马逊云科技 云技能孵化营——我的云技能之旅

文章目录 每日一句正能量前言活动流程后记 每日一句正能量 不能在已经获得足够多的成功时&#xff0c;还对自己的能力保持怀疑&#xff0c;露出自信的微笑&#xff0c;走出自信的步伐&#xff0c;做一个自信的人&#xff01; 前言 亚马逊云科技 (Amazon Web Services) 是全球云…

Kao框架学习

中间件&#xff1a;洋葱模型 这是官网上给出的示例&#xff0c;从logger依次往下执行&#xff0c;执行到最底层的response往回退&#xff0c;结构很像同心圆的洋葱从外层向内层再由内层向外层。 next表示暂停当前层的代码进入下一层&#xff0c; 当最后一层执行完毕开始回溯&a…

学习完毕JavaSE的感想

今天&#xff0c;把Java复习完毕了&#xff0c;之前学习的时候&#xff0c;学校里学的总是有限的 &#xff0c;自己上手操作之后才发觉差的很多&#xff0c;部署服务器发现要学操作系统&#xff0c;学完了web基础 &#xff0c;又发现还得学前后端分离vue react这些&#xff0c;…

基于ensp的中大型企业网络安全解决方案的设计与实施

一、需求背景 公司部门具体背景&#xff1a;公司共设有人事部、财务部、销售部、市场部四个部门以及一个员工宿舍楼&#xff0c;公司有对外互联网业务需要提供。公司内存在重要部门需要保护数据安全以及访问控制。 &#xff08;1&#xff09;根据客户需求、部门、拓扑&#xf…

代码搜索技巧

在IDE中搜索代码时&#xff0c;经常会被相近的无关代码干扰&#xff0c;如筛选所有使用协程的代码段&#xff0c; 可见有大量“噪音”。 可使用IDE提供的正则表达式功能 如 使用 \bgo ,即匹配go开头的&#xff0c;且之后为空格的所有选项 使用 \bgo func,即匹配到了所有使用协程…

C++学习vector

1,把list的相关函数都实现出来&#xff08;未完&#xff09; 2&#xff0c; 运行结果&#xff1a;

等保测评各个级别的详细内容

等保测评是指信息系统安全等级保护测评&#xff0c;是我国信息安全领域中的一项重要工作。根据国家标准《信息系统安全等级保护基本要求》(GB/T 22239-2008)和《信息系统安全等级保护测评技术要求》(GB/T 25070-2010)。 等保测评分为五个级别&#xff0c;分别是&#xff1a;一级…

达梦数据库管理用户和创建用户介绍

概述 本文主要对达梦数据库管理用户和创建用户进行介绍和总结。 1.管理用户介绍 1.1 达梦安全机制 任何数据库设计和使用都需要考虑安全机制&#xff0c;达梦数据库采用“三权分立”或“四权分立”的安全机制&#xff0c;将系统中所有的权限按照类型进行划分&#xff0c;为每…

JZ12 矩阵中的路径

剑指Offer编程链接&#xff1a;JZ12 题目描述&#xff1a; 思路&#xff1a;递归回溯的方法&#xff0c;总结一下什么情况需要使用递归&#xff1a; 递归在解决问题时&#xff0c;通常涉及以下情况&#xff1a; 问题可被分解为较小的相似子问题。子问题与原问题具有相同的结…

eclipse设置字体大小

打开IDE&#xff0c;选择window->perferences 选择颜色与字体&#xff0c;选择basic 选中text-font之后选择编辑 选择合适的大小之后选择应用并关闭即可 结果

权限提升-Windows本地提权-AT+SC+PS命令-进程迁移-令牌窃取-getsystem+UAC

权限提升基础信息 1、具体有哪些权限需要我们了解掌握的&#xff1f; 后台权限&#xff0c;网站权限&#xff0c;数据库权限&#xff0c;接口权限&#xff0c;系统权限&#xff0c;域控权限等 2、以上常见权限获取方法简要归类说明&#xff1f; 后台权限&#xff1a;SQL注入,数…

ELK日志收集系统

一、概述 1、ELK由三个组件构成 2、作用 日志收集 日志分析 日志可视化 3、为什么使用&#xff1f; 日志对于分析系统、应用的状态十分重要&#xff0c;但一般日志的量会比较大&#xff0c;并且比较分散。 如果管理的服务器或者程序比较少的情况我们还可以逐一…

数据结构学习 --4 串

数据结构学习 --1 绪论 数据结构学习 --2 线性表 数据结构学习 --3 栈&#xff0c;队列和数组 数据结构学习 --4 串 数据结构学习 --5 树和二叉树 数据结构学习 --6 图 数据结构学习 --7 查找 数据结构学习 --8 排序 本人学习记录使用 希望对大家帮助 不当之处希望大家帮忙纠正…

二极管:常用二极管封装

常用二极管封装 1、DO-41 2、DO-201AD 3、DO-35 4、LL-34 5、DO-214AC (SMA) 6、SMB

电脑数据丢失如何恢复?最常见的2种数据恢复方法!

大家使用电脑的时候是否有发生过不小心删除数据&#xff0c;或者数据不明丢失的情况呢&#xff1f;相信九成都是有的&#xff0c;那么当你的数据不小心删除或是丢失的话&#xff0c;有没有电脑数据恢复方法&#xff1f;其实很多人当自己电脑的数据丢失后&#xff0c;如果不是很…

一直傻傻分不清 count(*) count(id) count(1) 这次终于整明白了

COUNT(*)、COUNT(id) 和 COUNT(1) 是用于计算行数的 SQL 聚合函数&#xff0c;它们在某些方面有一些区别。 - COUNT(*)&#xff1a;COUNT(*) 是一种特殊的语法&#xff0c;它返回结果集中的行数&#xff0c;不考虑任何列的值。它会将表中的每一行都计数&#xff0c;包括含有NU…

ToBeWritten之威胁情报

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 转移发布平台通知&#xff1a;将不再在CSDN博客发布新文章&#xff0c;敬…

【LeetCode】剑指 Offer <二刷>(1)

目录 前言&#xff1a; 题目&#xff1a;剑指 Offer 03. 数组中重复的数字 - 力扣&#xff08;LeetCode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 前言&#xff1a; …