【APUE】网络socket编程温度采集智能存储与上报项目技术------多进程编程

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生在读,研究方向无线联邦学习
擅长领域:驱动开发,嵌入式软件开发,BSP开发
作者主页:一个平凡而乐于分享的小比特的个人主页
文章收录专栏:网络socket编程之温度采集智能存储与上报项目,本专栏为网络socket编程之温度采集智能存储与上报项目技术简介,实现流程分析
项目源码:https://gitee.com/TJF865975/project1_ds18b20,README部分包含项目功能及实现,欢迎大家Watch、Star、Fork。
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

1. 多进程编程基础知识

1.1 什么是进程?

在操作系统原理使用这样的术语来描述的:正在运行的程序及其占用的资源(CPU、内存、系统资源等)叫做进 程。站在程序员的角度来看,我们使用vim编辑生成的C文件叫做源码,源码给程序员来看的但机器不识别,这时我们需要使用 编译器gcc编译生成CPU可识别的二进制可执行程序并保存在存储介质上,这时编译生成的可执行程序只能叫做程序而不能叫进 程。而一旦我们通过命令(./a.out)开始运行时,那正在运行的这个程序及其占用的资源就叫做进程了。

1.2 进程空间内存布局

在这里插入图片描述
:栈内存由编译器在程序编译阶段完成,进程的栈空间位于进程用户空间的顶部并且是向下增长,每个函数的每次调用都会在栈空间中开辟自己的栈空间,函数参数、局部变量、函数返回地址等都会按照先入者为栈顶的顺序压入函数栈中,函数返回后该函数的栈空间消失,所以函数中返回局部变量的地址都是非法的。
:堆内存是在程序执行过程中分配的,用于存放进程运行中被动态分配的的变量,大小并不固定,堆位于非初始化数据段和栈之间,并且使用过程中是向栈空间靠近的。当进程调用 malloc 等函数分配内存时,新分配的内存并不是该函数的栈帧中,而是被动态添加到堆上,此时堆就向高地址扩张;当利用 free 等函数释放内存时,被释放的内存从堆中被踢出,堆就会缩减。因为动态分配的内存并不在函数栈帧中,所以即使函数返回这段内存也是不会消失。
非初始化数据段:通常将此段称为 bss 段,用来存放未初始化的全局变量和 static 静态变量。并且在程序开始执行之前,就是在 main()之前,内核会将此段中的数据初始化为 0 或空指针。
初始化数据段:用来保已初始化的全局变量和 static 静态变量。
文本段也称代码段:这是可执行文件中由 CPU 执行的机器指令部分。正文段常常是只读的,以防止程序由于意外而修改其自身的执行。

Linux 内存管理的基本思想就是只有在真正访问一个地址的时候才建立这个地址的物理映射,Linux C/C++语言的分配方式共有3 种方式。
(1)从静态存储区域分配。就是数据段的内存分配,这段内存在程序编译阶段就已经分配好,在程序的整个运行期间都存在,例如全局变量,static 变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是系统栈中分配的内存容量有限,比如大额数组就会把栈空间撑爆导致段错误。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用 malloc 或 new 申请任意多少的内存,程序员自己负责在何时用free 或 delete 释放内存。此 区域内存分配称之为动态内存分配。动态内存的生存期由我们决定,使用非常灵活,但问题也最多,比如指向某个内存块的指针取值发生了变化又没有其他指针指向 这块内存,这块内存就无法访问,发生内存泄露。

1.3 四次握手模型

在这里插入图片描述

2.实现函数

2.1 fork()系统调用

fork()系统调用会创建一个新的子进程,这个子进程是父进程的一个副本。这也意味着,系统在创建新的子进程成功后,会将父进程的文本段、数据段、堆栈都复制一份给子进程,但子进程有自己独立的空间,子进程对这些内存的修改并不会影响父进程空间的相应内存。这时系统中出现两个基本完全相同的进程(父、子进程),这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。如果需要确保让父进程或子进程先执行,则需要程序员在代码中通过进程间通信的机制来自己实现。

2.2 exec*()执行另外一个程序

在fork()之后紧接着调用exec*()系列的函数来让子进程去执行另外一个程序。其中exec*()是一些列的函数。

int execl(const char *path, const char *arg, ...); 
int execlp(const char *file, const char *arg, ...); 
int execle(const char *path, const char *arg, ..., char * const envp[]); 
int execv(const char *path, char *const argv[]); 
int execvp(const char *file, char *const argv[]);  

2.3 vfork()系统调用

在fork()之后常会紧跟着调用exec来执行另外一个程序,而exec会抛弃父进程的文本段、数据 段和堆栈等并加载另外一个程序,所以现在的很多fork()实现并不执行一个父进程数据段、堆和栈的完全副本拷贝。作为替代,使用了写时复制(CopyOnWrite)技术: 这些数据区域由父子进程共享,内核将他们的访问权限改成只读,如果父进程和子进程中的任何一个试图修改这些区域的时候,内核再为修改区域的那块内存制作一个副本。

vfork()是另外一个可以用来创建进程的函数,他与fork()的用法相同,也用于创建一个新进程。 但vfork()并不将父进程的地址 空间完全复制到子进程中,因为子进程会立即调用exec或exit(),于是也就不会引用该地址空间了。不过子进程再调用exec()或 exit()之前,他将在父进程的空间中运行,但如果子进程想尝试修改数据域(数据段、堆、栈)都会带来未知的结果,因为他会影响 了父进程空间的数据可能会导致父进程的执行异常。此外,vfork()会保证子进程先运行,在他调用了exec或exit()之后父进程才 可能被调度运行。如果子进程依赖于父进程的进一步动作,则会导致死锁。

2.4 system()与popen()函数

如果我们在程序中,想执行另外一个Linux命令时,可以调用fork()然后再exec执行相应的命令即可,但这样相对比较麻烦。Linux系统提供了一个system()库函数,该库函数可以快速创建一个进程来执行相应的命令。

int system(const char *command);

对于之前我们使用fork()+execl()函数来执行ifconfig命令,并将该命令执行的结果写入到文件后再来读取的实现,这个过程相对比较麻烦,另外涉及到了创建文件和读取文件的过程。其实也有另外一个函数popen()可以执行一条命令,并返回一个基于管道(pipe)的文件流,这样我们可以从该文件流中一行样解析了。

2.5 wait()与waitpid()函数

当一个进程正常或异常退出时,内核就会向其父进程发送SIGCHLD信号。因为子进程退出是一个异步事件,所以这种信号也是内核向父进程发送的一个异步通知。父进程可以选择忽略该信号,或者提供一个该信号发生时即将被执行的函数,父进程可以调用wait()或waitpid()可以用来查看子进程退出的状态。

pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

在一个子进程终止前,wait使其调用者阻塞,而waitpid有一选项可使调用者不用阻塞。 waitpid并不等待在其调用的之后的第一个终止进程,他有若干个选项,可以控制他所等待的进程。 如果一个已经终止、但其父进程尚未对其调用wait进行善后处理(获取终止子进程的有关信息如CPU时间片、释放它锁占用的资源如文件描述符等)的进程被称僵死进程(zombie),ps命令将僵死进程的状态打印为Z。如果子进程已经终止,并且是一个僵死进程,则wait立即返回该子进程的状态。所以,我们在编写多进程程序时,最好调用wait()或waitpid()来解决僵尸进程的问题。

此外,如果父进程在子进程退出之前退出了,这时候子进程就变成了孤儿进程。当然每一个进程都应该有一个独一无二的父进程,init进程就是这样的一个“慈父”,Linux内核中所有的子进程在变成孤儿进程之后都会被init进程“领养”,这也意味着孤儿进程的父进程最终会变成init进程。

3.多进程改写服务器程序

在了解Linux下多进程编程之后,我们就可以使用多进程编程模型改写服务器的多进程实现,其流程图如下:
在这里插入图片描述

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

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

相关文章

优先队列c++

内容&#xff1a; priority_quene是一个优先队列&#xff0c;优先级别高的先入队&#xff0c;默认最大值优先 因此出队和入队的时间复杂度均为O&#xff08;logn&#xff09;,也可以自定义优先级 头文件<quene> 函数&#xff1a; 构建优先队列 priority_queue<in…

C语言中的字符与字符串:魔法般的函数探险(续)

七、字符数组与字符串的关系 在C语言中&#xff0c;字符串实际上是以字符数组的形式存在的。了解这一关系&#xff0c;对于深入理解字符串函数和字符操作至关重要。 字符数组与字符串字面量&#xff1a;当我们定义一个字符串字面量&#xff0c;如char str[] "Hello"…

【资源分享】Eclipse最新版本免费安装下载

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

C++之函数提高(HM)

目录 1.函数默认参数&#xff08;缺省参数&#xff09; 2.占位参数 3.函数重载 4.类和对象--封装 &#xff08;1&#xff09;圆类&#xff1a; &#xff08;2&#xff09;访问权限 &#xff08;3&#xff09;struct&&class &#xff08;4&#xff09;立方体类的…

OAuth 2.0 的四种方式

RFC 6749 OAuth 2.0 的标准是 RFC 6749 文件。该文件先解释了 OAuth 是什么。 OAuth 引入了一个授权层&#xff0c;用来分离两种不同的角色&#xff1a;客户端和资源所有者。…资源所有者同意以后&#xff0c;资源服务器可以向客户端颁发令牌。客户端通过令牌&#xff0c;去请…

爬虫 新闻网站 并存储到CSV文件 以红网为例 V1.0

爬虫&#xff1a;红网网站&#xff0c; 获取当月指定关键词新闻&#xff0c;并存储到CSV文件 V1.0 目标网站&#xff1a;红网 爬取目的&#xff1a;为了获取某一地区更全面的在红网已发布的宣传新闻稿&#xff0c;同时也让自己的工作更便捷 环境&#xff1a;Pycharm2021&#…

Cisco交换机安全配置

Cisco交换机安全配置 前提 我们以下命令一般都要先进入Config模式 S1> enable S1# conf t S1(config)#端口安全保护 禁用未使用的端口 以关闭fa0/1到fa0/24的端口为例 S1(config)# interface range fa0/1-24 S1(config-if-range)# shutdown缓解MAC地址表攻击 防止CAM…

关联规则(理论及实例)

目录 一、啤酒和尿布的故事 二、理论 三、实例 1. 自定义数据集 2. 数据需转换成one-hot编码 3.电影题材关联分析 一、啤酒和尿布的故事 在美国&#xff0c;一些年轻的父亲下班后经常要到超市去购买婴儿尿布&#xff0c;超市因此发现一个规律&#xff0c;在购买婴儿尿布的…

微信小程序上传到gitee

共三步 1、新建gitee仓库 点号&#xff0c;新建仓库&#xff0c;填入仓库信息新建即可 2、修改版本管理参数 微信开发者工具中点开版本管理&#xff0c;未初始化&#xff0c;需要先点初始化 接下来将设置中的通用、网络认证、远程3个部分的参数填写好 通用&#xff1a;核对…

idea的后端环境配置

首先&#xff0c;在你刚打开idea时红色箭头所指的是你进行配置的地方&#xff0c;接下来我把具体步骤说一下 1&#xff0c;直接点击箭头所指的地方就会出现如图界面&#xff0c;然后点击Tomcat server,使其展开点击第一个 第二步取消勾选&#xff0c;第三步选择bin的上一级然后…

51单片机入门_江协科技_21~22_OB记录的笔记

21. LED点阵屏 21.1. LED点阵屏介绍 •LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合&#xff0c;如汽车报站器、广告屏以及公告牌等 •LED点阵屏分类 按颜色&#xff1a;单…

基于SpringBoot+Vue实现前后端分离的房屋租赁系统

一、&#x1f680;选题背景介绍 &#x1f4da;推荐理由&#xff1a; 计进行房屋租赁工作的管理&#xff0c;不仅能够保证各项信息准确无误、快速输出&#xff0c;同时计算机具有手工管理所无法比拟的优点&#xff0c;例如:检索迅速、查找方便、可靠性高、存储量大、保密性好、寿…

2024整理一些前端面试题库一

以下是一些2024年前端面试题及其答案&#xff1a; HTML、XML、XHTML之间的区别是什么&#xff1f; HTML是一种标记语言&#xff0c;用于创建网页&#xff0c;定义页面的结构和内容&#xff0c;如标题、段落、表格、链接、图片等。 XML&#xff08;可扩展标记语言&#xff09;…

screen服务器后台使用

screen服务器后台使用 想用远程服务器跑程序&#xff0c;想让自己的电脑关机后继续运行&#xff0c;可以使用screen 1.查看已有screen screen -ls2.删除screen screen -X -S 2758463 quit3.新建screen screen -S elsevier查看&#xff0c;显示创建成功&#xff1a; 4.切…

免费的 AIGC工具( 7个 )

人工智能技术有好的一方面&#xff0c;又不好的地方&#xff0c;要区别对待&#xff0c;吸取精华&#xff0c;去其糟粕。目前市场上有很多AI大模型&#xff0c;可以支持聊天&#xff0c;写文稿&#xff0c;创作等&#xff0c;部分可以生成图片&#xff0c;以下是7个很不错的免费…

2024/4/5 AT24C02 总线(I²C总线)

存储器的介绍&#xff1a; 一、易失性存储器RAM&#xff1a;存储速度快&#xff0c;掉电丢失 SRAM&#xff08;静态RAM&#xff09;&#xff1a;极快DRAM&#xff08;动态RAM&#xff09;&#xff1a;需要配一个扫描电路&#xff0c;进行“补电”&#xff08;动态刷新&#x…

02 _ 分布式系统的指标:啥是分布式的三围

你好&#xff0c;我是聂鹏程。 在上一篇文章中&#xff0c;通过对分布式发展历程的学习&#xff0c;我们对分布式技术有了一个整体印象。接下来&#xff0c;我们就再来看看可以用哪些指标去具体地衡量一个分布式系统。如果你已经对分布式系统的指标了解得很清楚了&#xff0c;…

刷题之Leetcode34题(超级详细)

34. 在排序数组中查找元素的第一个和最后一个位置 力扣链接(opens new window)https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/ 给定一个按照升序排列的整数数组 nums&#xff0c;和一个目标值 target。找出给定目标值在数组中的开始…

Jenkins 安装部署

1、安装下载 官网地址&#xff1a;Jenkins 下载 war 包 1、前置环境 JDK 环境&#xff08;根据 Jenkins 版本不同&#xff0c;需要的 JDK 版本不同&#xff0c;目前需要 JDK11 的版本来支持&#xff09;Maven maven 官网下载压缩包 &#xff0c;并将其传输到服务器&#xf…

【Python】免费的图片/图标网站

专栏文章索引&#xff1a;Python 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 这里是我收集的几个免费的图片/图标网站&#xff1a; iconfont-阿里巴巴矢量图标库icon&#xff08;.ico&#xff09;INCONFINDER&#xff08;.ico&#xff09;