Linux学习之系统编程2(关于进程及其相关的函数)

写在前面:

我的Linux的学习之路非常坎坷。第一次学习Linux是在大一下的开学没多久,结果因为不会安装VMware就无疾而终了,可以说是没开始就失败了。第二次学习Linux是在大一下快放暑假(那个时候刚刚过完考试周),我没什么事做就又重拾Linux,不服输的我选择再战Linux,这一次学习还算顺利,虽然中间有些小插曲但是不影响整体学习进度, 我看着B站上的视频一点点学习Linux,基本上把Linux的基础指令学完了。学完之后我又遇到问题了,视频基本上到这就结束了,而我却不知道下一步该学什么,于是就没怎么碰Linux,结果没过多长时间我就把学的Linux指令忘的一干二净。现在是我第三次学习Linux,我决定重新开始学Linux,同时为了让自己学习的效果更好,我选择以写blog的形式逼迫自己每天把学习到的Linux知识整理下来。这也就是我写这个系列blog的原因。


基础概念介绍

关于进程和程序

程序:死的。只占用磁盘空间。
进程:活的。运行起来的程序。占用内存、cpu 等系统资源。

我们可以把程序比作剧本进程比作戏。把剧本演绎起来就是戏(程序运行起来就是进程),剧本可以在不同的戏台上演绎,也可以让不同的人来演绎(程序可以不同的环境上运行,也可以用不同的系统资源来运行),这样可以更方便理解。

关于cpu

cpu

虚拟内存和物理内存映射关系

mem
不同程序在物理内存的0-3G部分经过MMU映射到不同的虚拟内存,而在物理内存的3G-4G经过MMU映射后到相同的虚拟内存。

PCB 进程控制块

PCB进程控制块:

  • 进程 id
  • 文件描述符表
  • 进程状态: 初始态、就绪态、运行态、挂起态、终止态
  • 进程工作目录位置
  • 信号相关信息资源
  • 用户 id 和组 id
    pcb

环境变量

  • echo $PATH 查看环境变量
  • echo $TERM 查看终端
  • echo $LANG 查看语言
  • env 查看所有环境变量

path 环境变量里记录了一系列的值,当运行一个可执行文件时,系统会去环境变量记录的位置里查找这个文件并执行。
这些查看环境变量的还有很多,我这里就只是写了几个最常见的的。


fork函数

fork介绍

1
这个函数使用起来非常简单,不用传入参数,就一个int的返回参数。我们先来看看返回参数。
2
我们乍一看可能觉得有点古怪,一个函数怎么能返回两个值呢?

  • 成功时,在父进程中返回子进程的PID,在子进程中返回0。这其实并没有矛盾,因为fork之后,就有两个进程,两个进程返回两种值。
  • 失败时,在父进程中返回-1,没有子进程被创建,errno被设置。

父子进程相同

  • data 段、text 段、堆、栈、环境变量、全局变量
  • 宿主目录位置
  • 进程工作目录位置
  • 信号处理方式

父子进程不同

  • 进程 id
  • 返回值
  • 各自的父进程
  • 进程创建时间
  • 闹钟
  • 未决信号集

父子进程共享

读时共享,写时复制————全局变量

  1. 文件描述符
  2. mmap映射区

实例

我们以循环创建N个子进程为例
源代码(代码里用到getpid getppid这两个函数,不懂的先不用管,我后面会介绍):

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

int main()
{
        pid_t pid;
        int i;
        printf("-------start1---------\n");
        printf("-------start2---------\n");
        printf("-------start3---------\n");
        printf("-------start4---------\n");
        for(i=0;i<5;i++)
        {
                pid=fork();
                if(pid==0)
                        break;
        }
        if(i==5)
        {
                sleep(i);
                printf("I'm parent,my pid is %d,my parent id is %d\n",getpid(),getppid());
        }
        else
        {
                sleep(i);
                printf("I'm %dth child,my pid is %d,my parent id is %d\n",i+1,getpid(),getppid());
        }
        return 0;
}

效果:
3
可能会犯的错误:

  • for循环中没有判断pid==0跳出循环。如果没有判断跳出,那就不是创造5个进程。
  • 很多人在第一次写的时候发现子进程出来的顺序并没有按照自己创建的顺序,并且每一次执行都不一样。这是因为每个子进程被创建出来后,都要去争抢CPU资源,谁抢到了就可以打印,虽然可能第一个子进程被创建早一些,但是这早一点的时间对于抢CPU并没有什么太大的优势。所以我们就可以人为加一个sleep来控制每个子进程打印的顺序。(必须要说的是,不加sleep这样的人为控制的,也可以成功创建5个子进程,这样只不过让这个过程更可视化)

getpid和getppid函数

1

这两个函数非常简单,看名字就知道getpid()是取得该进程的pidgetppid是取得该进程的父进程的pid.
具体的实例可以参考上面的代码。


exec函数族

exec函数族:使进程执行某一程序。成功无返回值,失败返回 -1。

1

参数解读:

int execlp(const char* file,const char * arg,.....)为例(借助 PATH 环境变量找寻待执行程序)

  • 参数1,程序名
  • 参数2,argv[0]
  • 参数3,argv[1]
  • 最后一个参数,哨兵,NULL

举例说明

execl

源代码:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
        pid_t pid=fork();
        if(pid==0)
        {
                execl("./test","./test",NULL);
                perror("execl error");
                exit(1);
        }
        else
        {
                sleep(1);
                printf("i am father\n");
        }
        return 0;
}

效果:
2

这里是展示execl函数,execl函数可以执行自定义的程序,也可以执行系统命令。并且要注意第一个参数是路径,不是文件名。

execlp

源代码:

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

int main()
{
        pid_t pid;
        printf("--------------start----------\n");
        pid=fork();
        if(pid==-1)
        {
                perror("fork error");
                exit(1);
        }
        if(pid==0)
        {
                execlp("ls","ls","-l","-h","-a",NULL);
                perror("execlp error");
                exit(1);
        }
        if(pid>0)
        {
                sleep(1);
                printf("I'm father,my child id is %d,my id is %d\n",pid,getpid());
        }
        return 0;
}

效果:
3

execlp用来执行一些系统命令

综合实例

我们实现一个功能,把ps aux的信息写入一个文件。
源代码:

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>

void sys_error(char* s)
{
        perror(s);
        exit(1);
}

int main()
{
        int fd;
        fd=open("exec.txt",O_RDWR | O_CREAT,0644);
        if(fd<0)
                sys_error("open file");
        dup2(fd,STDOUT_FILENO);
        execlp("ps","ps","aux",NULL);
}

效果:
4

exec 函数一旦调用成功,即执行新的程序,不返回。只有失败才返回,错误值-1,所以通常我们直接在 exec 函数调用后直接调用perror(),和 exit(),无需 if 判断。

  • l (list) 命令行参数列表
  • p (path) 搜索 file 时使用 path 变量
  • v (vector) 使用命令行参数数组
  • e (environment) 使用环境变量数组,不适用进程原有的环境变量,设置新加载程序运行的环境变量

事实上,只有 execve 是真正的系统调用,其他 5 个函数最终都调用 execve,是库函数,所以execve man 手册第二节,其它函数在 man 手册第 3 节。


孤儿进程和僵尸进程

孤儿进程:

父进程先于子进终止,子进程沦为“孤儿进程”,会被 init 进程领养。

僵尸进程:

子进程终止,父进程尚未对子进程进行回收,在此期间,子进程为“僵尸进程”。 kill 对其无效。这里要注意,每个进程结束后都必然会经历僵尸态,时间长短的差别而已。子进程终止时,子进程残留资源 PCB 存放于内核中,PCB 记录了进程结束原因,进程回收就是回收 PCB。回收僵尸进程,得 kill 它的父进程,让孤儿院去回收它。


写在最后

个人亲身经验:我们学习的一系列Linux命令,一定要自己亲手去敲。不要只是看别人敲代码,不要只是停留在眼睛看,脑袋以为自己懂了,等你实际上手去敲会发现许许多多的这样那样的问题。正可谓“键盘敲烂,月薪过万


如果你觉得我写的题解还不错的,请各位王子公主移步到我的其他题解看看

  1. 数据结构与算法部分(还在更新中):
  • C++ STL总结 - 基于算法竞赛(强力推荐
  • 动态规划——01背包问题
  • 动态规划——完全背包问题
  • 动态规划——多重背包问题
  • 动态规划——分组背包问题
  • 动态规划——最长上升子序列(LIS)
  • 二叉树的中序遍历(三种方法)
  • 最长回文子串
  • 最短路算法——Dijkstra(C++实现)
  • 最短路算法———Bellman_Ford算法(C++实现)
  • 最短路算法———SPFA算法(C++实现)
  • 最小生成树算法———prim算法(C++实现)
  • 最小生成树算法———Kruskal算法(C++实现)
  • 染色法判断二分图(C++实现)
  1. Linux部分(还在更新中):
  • Linux学习之初识Linux
  • Linux学习之命令行基础操作
  • Linux学习之基础命令(适合小白)
  • Linux学习之权限管理和用户管理
  • Linux学习之制作静态库和动态库
  • Linux学习之makefile
  • Linux学习之系统编程1(关于读写系统函数)

✨🎉总结

“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”
在这里插入图片描述
如果有错误❌,欢迎指正哟😋

🎉如果觉得收获满满,可以动动小手,点点赞👍,支持一下哟🎉

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

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

相关文章

k8s快速搭建

VMware16Pro虚拟机安装教程VMware16.1.2安装及各版本密钥CentOS7.4的安装包:提取码&#xff1a;lp6qVMware搭建Centos7虚拟机教程 搭建完一个镜像 关机 拍摄一个快照,克隆两个作为子节点 0. 环境准备 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#…

实验三-HBase数据库操作

第一步&#xff1a;首先登陆ssh&#xff0c;之前设置了无密码登陆&#xff0c;因此这里不需要密码&#xff1b;再切换目录至/usr/local/hadoop &#xff1b;再启动hadoop ssh localhost cd /usr/local/hadoop ./sbin/start-dfs.sh 输入命令jps&#xff0c;能看到NameNode,Data…

环境准备-VMware安装

照顾到很多人不是很会环境搭建,我这里会将搭建的步骤讲的细致点 第一步,VMware下载。目的是通过VMware搭建Linux服务器,因为大家大部分还是Windows的电脑,我们先下载虚拟机搭建一个Linux系统的服务器 下载完成之后,点击安装,如下: 点击“下一步” 勾选“我接受许可协议…

算法导论复习——CHP24 单源最短路

单源最短路径问题&#xff1a; 给定一个图G (V,E)&#xff0c;找出从给定的源点s∈V到其它每个结点v∈V的最短路径。 这样最短路径具有最优子结构性&#xff1a;两个结点之间的最短路径的任何子路径都是最短的。 基本概念 负权边&#xff1a;权重为负值的边称为负权重的边。 如…

AI计算,为什么要用GPU?

今天这篇文章&#xff0c;我们继续来聊聊芯片。 在之前的文章里&#xff0c;小枣君说过&#xff0c;行业里通常会把半导体芯片分为数字芯片和模拟芯片。其中&#xff0c;数字芯片的市场规模占比较大&#xff0c;达到70%左右。 数字芯片&#xff0c;还可以进一步细分&#xff0…

工具分享:有哪些开源知识库可以使用?

导语&#xff1a; 在信息爆炸的时代&#xff0c;我们常常需要从各种渠道获取知识和解决问题。开源知识库为我们提供了一个便捷的途径&#xff0c;让我们可以轻松地分享和获取知识。本文将介绍5个开源知识库&#xff0c;其中包括HelpLook&#xff0c;帮助你更好地解决问题。 1…

Nacos 持久化及集群的搭建【微服务】

文章目录 一、统一配置管理二、微服务配置拉取三、配置热更新四、多环境共享配置五、Nacos 集群搭建1. 集群结构2. 初始化数据库3. 搭建集群 六、Nginx 反向代理七、启动项目测试 一、统一配置管理 案例练习的时候我们只有两个微服务&#xff0c;管理起来非常简单&#xff0c;但…

8个超高清图片素材网站,免费下载,真的很实用~

图片真的是我们日常生活中必不可少的一部分&#xff0c;大到工作&#xff0c;小到发朋友圈都需要配图&#xff0c;那除了自己拍摄之外&#xff0c;哪里还能找到精美又高清的图片素材呢&#xff1f;本期就给大家整理了8个可免费下载的图片素材网站&#xff0c;真的免费下载&…

大创项目推荐 深度学习动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

揭秘VVIC API接口:引领数据交互新潮流,赋能开发者无限可能

一、引言 VVIC API接口为开发者提供了一种高效、安全的方式&#xff0c;用于获取VVIC平台上的各类数据和服务。通过该接口&#xff0c;开发者可以将VVIC的丰富资源集成到自己的应用或网站中&#xff0c;从而为用户提供更加优质和便捷的服务。 二、VVIC API接口的种类与功能 …

Vue - 多行文本“展开、收起”功能

TextClamp 使用 js 实现文本展开、收起&#xff0c;并非纯 CSS 实现。 Props&#xff1a; fontSize&#xff1a;Number&#xff0c;默认&#xff1a;14lines&#xff1a;Number&#xff0c;默认&#xff1a;1lineHeight&#xff1a;Number&#xff0c;默认&#xff1a;20 F…

odoo与superset集成(二)

继上篇文章odoo与superset集成再次进行superset深度集成 odoo 目前的报表都是需要通过代码定制化的且需要升级发版。 而且图表类型单一&#xff0c;不满足市场的需求。 故 本次把superset 整个看板集成到odoo中进行展示 功能&#xff1a; 1、看板集成展示 2、单点登录supers…

Java解析xml文档,判断对象是一个json是jsonArray还是jsonObject

有一篇xml文档&#xff0c;如下&#xff1a; 现在需要解析出其中的内容&#xff0c;首先需要明确的是&#xff0c;文档是由一个个的标签嵌套形成的&#xff0c;例如整个xml文件是由许多DescriptorRecord标签构成&#xff0c; <DescriptorRecord DescriptorClass "1&…

Oracle-数据库迁移之后性能变慢问题分析

问题背景&#xff1a; ​一套Oracle11.2.0.4的RAC集群&#xff0c;通过Dataguard switchover方式迁移到新机器之后&#xff0c;运行第一天应用报障说应用性能慢&#xff0c;需要进行性能问题排查 问题分析&#xff1a; 首先&#xff0c;登陆到服务器&#xff0c;用TOP看一眼两个…

MCMC:Metropolis-Hastings抽样

马尔可夫链有两个要素&#xff1a; 一步转移概率矩阵&#xff1a;初始分布&#xff1a; 如果这两个要素都确定了&#xff0c;这个链的转移行为就被完全确定下来了。我们就可以求得极限分布 &#xff0c;只需解下面这个方程即可。 但是MCMC试图解决的问题刚好是反过来。即已知…

微同城生活源码系统:专业搭建本地生活服务平台 附带完整的安装部署教程

随着移动互联网的普及&#xff0c;人们越来越依赖手机进行日常生活中的各种活动&#xff0c;包括购物、餐饮、娱乐等。而传统的本地生活服务平台往往存在着功能单一、用户体验差等问题&#xff0c;无法满足用户日益增长的需求。因此&#xff0c;开发一款功能强大、易用性强的本…

HubSpot电子邮件自动化的关键功能和流程!

HubSpot提供了强大的电子邮件自动化工具&#xff0c;使用户能够创建、执行和跟踪复杂的电子邮件市场营销活动。以下是HubSpot电子邮件自动化的一些关键功能和流程&#xff1a; 1.电子邮件工作流程&#xff08;Email Workflows&#xff09;&#xff1a; 用户可以使用HubSpot的工…

达梦数据库报错 执行失败(语句1) -2111: 第1 行附近出现错误: 无效的列名[system]

[TOC](达梦数据库报错 执行失败(语句1) -2111: 第1 行附近出现错误: 无效的列名[system]) 1、报错现象 执行下列sql语句 UPDATE "TEST"."TEST_1" SET "TEST_1"."SALT"123456 where "TEST_1"."ID""system&…

境内深度合成服务算法备案清单(2023年12月)

截止2024年1月3日&#xff0c;第三批深度合成服务算法备案信息的公告尚未发布&#xff0c;预计将会在2024-1-10左右发布&#xff0c;我公司已知晓部分公示名单&#xff0c;如中国电信数字人生成算法&#xff0c;详情联系WX号&#xff1a;SuanfabeiandayuAI生成合成类算法应办理…

「Qt Widget中文示例指南」如何实现一个日历?(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文中的CalendarWi…