【Linux系统化学习】守护进程 | 序列化和反序列化

目录

前言

守护进程

会话

进程组

setsid系统调用

守护进程系统调用

再谈协议

序列化和反序列化

Json


前言

上两篇文章我们所编写的服务器,并算不上真正意义上的服务器一般的服务器都是要随时能够访问的,就像我们在任何时间段都可以打开抖音获取视频资源;要想实现只需要将我们的进程变成守护进程(精灵进程)。

守护进程

会话

当我们使用xshell登录我们自己的服务器时操作系统会给登录用户提供:

  1. 命令行解释器(bash)
  2. 提供一个终端(给用户提供命令解析服务)

这个终端就是会话

进程组

当我们在同时运行多个进程时,shell就会将这几个进程归为一个组即进程组;因此进程组是一组相关联进程的集合,并且每一个进程组的第一个进程的ID为进程组ID。当只有一个进程启动的时候称为自成进程组。

前面说过任何时刻一个会话内部,可以包含很多进程组,但是默认时刻只允许一个进程组在前台也就是前台进程。当运行我们的服务器时,就是这种前台进程的状态;但是当我们退出xshell时,进程也就随之终止,被释放资源了;达不到一直运行的状态;因此我们可以将我们的进程转化为守护进程。

setsid系统调用

setsid 执行以下操作:

  1. 创建新的会话:它创建了一个新的会话,与当前的终端会话分离开来。这意味着即使当前的终端关闭,该会话也会继续存在。

  2. 设置当前进程为会话领导者setsid 将当前进程的进程ID设置为新会话的领导者(session leader)。这意味着当前进程成为了新会话中的第一个进程,并且没有父进程。

  3. 脱离终端:因为新的会话已经创建,setsid 将当前进程从其原始的控制终端分离开来。这样即使启动进程的终端关闭,该进程也不会受到影响。

但是单个的自成进程组是不可以调用这个系统调用的,因此我们可以创建子进程后父进程直接退出,让1号进程领养子进程,在子进程中调用这个系统调用。

Daemon.hpp

#pragma once

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

const char *root = "/";
const char *dev_null = "/dev/null";

void Daemon(bool ischdir, bool isclose)
{
    // 1. 忽略可能引起程序异常退出的信号
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);

    // 2. 让自己不要成为组长
    if (fork() > 0)
        exit(0);

    // 3. 设置让自己成为一个新的会话, 后面的代码其实是子进程在走
    setsid();

    // 4. 每一个进程都有自己的CWD,是否将当前进程的CWD更改成为 / 根目录
    if (ischdir)
        chdir(root);

    // 5. 已经变成守护进程啦,不需要和用户的输入输出,错误进行关联了
    if (isclose)
    {
        close(0);
        close(1);
        close(2);
    }
    else
    {
        // 这里一般建议就用这种
        int fd = open(dev_null, O_RDWR);
        if (fd > 0)
        {
            dup2(fd, 0);
            dup2(fd, 1);
            dup2(fd, 2);
            close(fd);
        }
    }
}

 注:

  • 要忽略可能引起进程异常终止的信号
  • 不可以使用三个标准IO流
  • 将标准IO流重定向,或者写入到系统的dev_null特殊文件中,IO对于这个文件都没有用

守护进程系统调用

上面的是我们通过系统调用setsid自主 实现的一种守护进程的方式,在系统中有直接的创建守护进程的系统调用。

int daemon(int nochdir, int noclose);

参数

  • nochdir:如果为非零值,表示不改变当前工作目录为根目录(/)。如果为零,表示将当前工作目录改变为根目录。
  • noclose:如果为非零值,表示不关闭标准输入、标准输出和标准错误文件描述符。如果为零,表示关闭这些文件描述符。

返回值

  • 如果成功,返回 0。
  • 如果失败,返回 -1,并设置 errno。

工作原理

  • 首先,daemon 函数会调用 fork 来创建一个子进程。
  • 子进程会调用 setsid 来创建一个新的会话,并成为该会话的领导者。
  • 如果 nochdir 参数为零,子进程会将当前工作目录更改为根目录(/)。
  • 如果 noclose 参数为零,子进程会关闭标准输入、标准输出和标准错误文件描述符。
  • 最后,子进程会返回 0,然后父进程退出。

 工作原理和我们上面自主实现的工作原理一模一样。

再谈协议

前面的文章我们简单说过协议就是对于通信双方来说就一种商量好的约定;但是socket api的接口都是按照”字符串“的方式来发送和接受的,如果我们要传送结构化的数据怎么办。

例如:如我们今天想制作一个网络版本的计算器;作为客户端来说我们要发送的是两个操作数和一个操作符,作为接收端我们收到的数据也是两个操作数和一个操作符,将发来的数据进行处理后;服务端我们是不是要发送运算结果和运算状态,在发送给客户端。

通过上面的例子我们可以将接收和发送的数据,设计为一个结构体;将这个结构体作为传输的基本数据结构,让客户端和服务端通信双方都遵守这个规则即可,这就是协议;

序列化和反序列化

在网络部分开始的时候我们就提到过TCP协议是面向字节流的,如果今天我们要使用TCP协议通信传输结构化的数据来实现上面的网络版本计算机,会遇到很多问题。

  • 对于语言来说,如果通信双方是使用不同的语言来编写的;对于不同的语言结构体定义和使用都不同;
  • 对于平台来说:结构体含有内存对齐,不同编译器和不同平台对结构体的内存布局可能有所不同,这可能导致在通信过程中出现数据的错位或填充。
  • 对于协议来说:TCP协议是面向字节节流的,如果只能发固定的字节,而这个固定的字节却不能支持一个完整的结构体,对于服务端来说如何处理不完整的数据

基于上面的问题,作为客户端就要将定义好的结构化数据转化为”字符串“字节流,这个过程就是序列化。

作为服务端我们收到的是”字符串“字节流,我们要将这个字节流转化为通信双方约定好的结构化数据,这个过程就是反序列化。

Json

简单来说序列化和反序列化就是将要发送的数据转化为字符串,将接收的数据转化为结构化的数据。也就是对字符串进行操作,如果我们自己实现这个过程,很麻烦也很容易出错;我们可以使用Json、protobuff、xml用来代替我们自主实现繁琐的字符转换。

注意:

  • TCP协议是全双工的,并且作为服务器和客户端双方是对等的;都可以进行收发消息。
  • 应用层用户通过write、send或者read、recv进行收发消息时只是将消息拷贝到内核TCP协议发送或者接收的缓冲区中、由协议决定缓冲区中的数据什么时候发送、发送多少、出错了怎么办;哪些函数只是拷贝函数。
  • TCP实际通信的时候其实是双方操作系统之间进行通信
  • 在用户层面你认为你发送了多少字节,但是对方比一定就要收多少字节
  • 自主实现协议的时候一定要明确字节流和字节流之间的边界,确保接收端读到完整的一个字节流
  • 生产者消费者模型的一种,任意一方向网络中放数据,一方从网络中取数据

今天对Linux中守护进程、序列化和反序列化的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法;个人主页还有很多精彩的内容。您三连的支持就是我前进的动力,感谢大家的支持!!! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[C++核心编程-09]----C++类和对象之继承

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

【MQTT】paho.mqtt.cpp 库的 介绍、下载、交叉编译、MQTT客户端例子源码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-05-13 1…

实习大学生如何在Purple Pi OH鸿蒙开发板下调试Android串口?

本文适用于Purple Pi OH在Android固件后串口的开发与使用。触觉智能的Purple Pi OH鸿蒙开源主板&#xff0c;是华为Laval官方社区主荐的一款鸿蒙开发主板。 该主板主要针对学生党&#xff0c;极客&#xff0c;工程师&#xff0c;极大降低了开源鸿蒙开发者的入门门槛&#xff0c…

Ubuntu系统搭建Tipask开源问答系统并发布公网分享好友远程访问

文章目录 1. 前言2.Tipask网站搭建2.1 Tipask网站下载和安装2.2 Tipask网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 4. 公网访问测试5. 结语…

神经网络复习--数学相关基础知识

文章目录 矩阵范数卷积激活函数信息熵 矩阵 标量&#xff1a;一个标量就是一个单独的数向量&#xff1a;一个向量是一列数。这些数是有序排列的。通过次序中的索引&#xff0c;我们可以确定每个单独的数矩阵&#xff1a;矩阵是一个二维数组&#xff0c;其中的每个元素被两个索…

基于网络的无人海洋船舶控制

书籍&#xff1a;Network-Based Control of Unmanned Marine Vehicles 作者&#xff1a;Yu-Long Wang&#xff0c;Qing-Long Han&#xff0c;Chen Peng&#xff0c;Lang Ma 出版&#xff1a;Springer 书籍下载-《基于网络的无人海洋船舶控制》控制系统中的通信网络可能引起延…

IDC 权威认可!Aloudata 入选金融领域中数据管理分析服务最佳实践案例

近日&#xff0c;国际知名数据咨询机构 IDC 重磅发布了《IDC PeerScape&#xff1a;金融领域中数据管理分析服务最佳实践案例》报告&#xff0c;Aloudata 与招商银行联合打造的 DDH 数据研发运维一体化平台成功入选&#xff0c;Aloudata 的技术、产品实力&#xff0c;以及在金融…

英语学习笔记12——名词所有格的运用

Whose is this … ? This is my/your/his/her … 这……是谁的&#xff1f;这是我的 / 你的 / 他的 / 她的…… Whose is that … ? That is my/your/his/her … 那……是谁的&#xff1f;那是我的 / 你的 / 他的 / 她的…… 词汇 Vocabulary father n. 爸爸 口语&#xf…

【Java】引用

变量的实质是一小块内存单元&#xff0c;这一小块内存里存储着变量的值 而当变量指向一个对象时&#xff0c;这个变量就被称为引用变量 比如 A anew A(); a 就是引用变量&#xff0c;它指向了一个A对象&#xff0c;也可以说它引用了一个A对象 我们通过操纵这个a来操作A对象。…

【RabbitMQ】消息队列 - RabbitMQ的使用记录

目录 一、什么是消息队列 二、什么是RabbitMQ 三、安装RabbitMQ 3.1 安装Erlang环境 3.2 安装RabbitMQ 3.3 打开服务管理界面 3.4 常用命令 四、Python示例代码 4.1 发送数据 4.2 接收数据 一、什么是消息队列 消息队列(Message Queue)是一种用于在应用程序之间传递消…

Docker 部署 Prometheus 实现一个极简的 QPS 监控

背景 : Prometheus 是近年来最流行的开源监控框架, 其功能强大且易于使用, 拥有各种主流后端语言(Java/Go/Python/Node.js等)与各种场景(如web handler/ k8s/Nginx/MySQL等)的客户端, 并自带图形化显示页面。分享一个快速入门Prometheus 的教程, 实现一个极简的, 后端开发需要特…

ICRA 2024 成果介绍:基于 RRT* 的连续体机器人高效轨迹规划方法

近来&#xff0c;连续体机器人研究受到越来越多的关注。其灵活度高&#xff0c;可以调整形状适应动态环境&#xff0c;特别适合于微创手术、工业⽣产以及危险环境探索等应用。 连续体机器人拥有无限自由度&#xff08;DoF&#xff09;&#xff0c;为执行空间探索等任务提供了灵…

有了这玩意,分分钟开发公众号功能!

大家好&#xff0c;我是程序员鱼皮。 不论在企业、毕设还是个人练手项目中&#xff0c;很多同学或多或少都会涉及微信相关生态的开发&#xff0c;例如微信支付、开放平台、公众号等等。 一般情况下&#xff0c;我们需要到官网查阅这些模块对应的 API 接口&#xff0c;自己编写…

数据结构(Java实现):顺序表

目录 1. 线性表2.顺序表2.1自己实现一个List接口2.2 IList接口的实现2.3 测试代码 1. 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、…

下载npm I就包错解决方案

npm i xxxx -S --legacy-peer-deps 如果包错就执行以上命令

【CSP CCF记录】202209-1 如此编码

题目 过程 C中"/"的使用 当a和被b均为int, long, char这样的整数类型&#xff0c;此时除法运算的结果为所得商的整数部分&#xff0c;例如&#xff1a;180/100&#xff0c;结果为1&#xff1b; int a 180;int b a / 100;cout << b << endl;#结果为1当…

用Arm CCA解锁数据的力量

安全之安全(security)博客目录导读 目录 CCA将如何改变Arm架构呢? 在实践中部署CCA 释放数据和人工智能的全部力量和潜力 早期计算中最大的挑战之一是管理计算资源&#xff0c;以最大化计算效率同时提供给不同程序或用户分配资源的分离。这导致了我们今天大多数使用的时间…

windows安装DrawDB

下载 新建一个目录drawdb,使用git下载&#xff0c;如果没有安装git的话&#xff0c;进入git官网进行下载windows版本 https://git-scm.com/downloads。 空白地方鼠标右键&#xff0c;打开git终端 执行命令&#xff1a; git clone https://github.com/drawdb-io/drawdb 安装依…

阿里巴巴找黄金宝箱(II) - 贪心思维

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输出描述三、输入描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布自己的解题思路&#xff0c;希望大家多指教 一、题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上&#xff0c;无意中发…

【自动驾驶技术栈学习】1-硬件《大话自动驾驶》| 综述要点总结 by.Akaxi

----------------------------------------------------------------------------------------------------------------- 致谢&#xff1a;感谢十一号线人老师的《大话自动驾驶》书籍&#xff0c;收获颇丰 链接&#xff1a;大话自动驾驶 (豆瓣) (douban.com) -------------…