Linux(二)进程概念

news2024/11/17 22:17:00

目录

一、冯诺依曼体系结构

二、操作系统

 三、进程概念

1、程序与进程的区别:

2、cpu分时机制

3、pcb——进程控制块

4、进程是什么?

四、进程状态

1、linux状态

2、僵尸态

pid_t fork(void):

fork创建进程之后,父子进程谁先运行?

僵尸进程

孤儿进程

 守护进程

五、fork()  创建一个子进程

1、返回值

2、创建子进程再认知

3、创建僵尸进程(滑稽)

4、当子进程成为僵尸进程时,父进程退出了!

5、僵尸进程如何进行处理?

6、孤儿进程

7、孤儿进程退出后会成为僵尸进程嘛?

六、环境变量

1、概念

2、优点

3、命令env

LS_COLOR颜色标记变量

 PATH路径变量

 4、其他指令

 七、环境变量的访问

 1、getenv()接口 :获取用来获取环境变量的值

 2、main函数参数

 打印argv运行参数:

打印env环境变量:

 3、全局变量 extern char **environ;


一、冯诺依曼体系结构

由冯.诺依曼提出来的关于计算机硬件体系结构:

输入设备:键盘

输出设备:显示器

存储器:内存

运算器&控制器:中央处理器-CPU

 CPU想要处理数据,是从内存中取出数据进行处理的,--CPU想要执行一个程序,第一件事就是先把程序从硬盘加载到内存中。

二、操作系统

本质:就是一个软件程序

功能:控制和管理计算机上的软硬件资源

目的:使计算机更加好久

完整的操作系统:内核+外部应用

我们所说的LInux就是Linux内核

计算机大体应用层次:用户->应用软件程序->系统调用接口->(操作系统)->驱动程序->硬件

 系统调用接口:操作系统内核向上提供的用于访问内核指定功能的接口

库函数: 就是对系统调用接口的进一步封装

库函数就是为了让这些系统调用接口在用户或者说程序员,让他们使用的时候更加容易

 三、进程概念

1、程序与进程的区别:

        程序是一堆指令集+数据 躺尸在硬盘上

        而进程是运行中的程序

 运行中的程序有很多,cpu应该先处理哪一个呢?

2、cpu分时机制

由操作系统进行控制管理,一个程序只在cpu上运行很短一段时间(一个时间片),然后切换到下一个程序,cpu处理每一个程序只会有一个时间片的时间,时间片运行完了就切换到下一个。

那如果是这样进行时间片轮转运行的,那么同一个程序cpu如何知道这个程序上次运行的情况呢?

3、pcb——进程控制块

操作系统需要对一个程序的运行状态进行描述(比如上次时间片轮转处理到哪个数据了)都要把cpu寄存器上的数据给保存下来,等到下次重新切换回来的时候,在把这些数据重新加载到寄存器上。

而这个对程序运行过程的描述,就叫做pcb——进程控制块,在linux下是一个task_struct结构体

操作系统调度管理程序运行就是通过pcb来实现的,那么之前的cpu分时机制也就可以正常运行了。

4、进程是什么?

进程是运行中的程序,这样回答很片面,因为这是站在用户的角度进行的描述。

在操作系统角度,进程就是系统对运行中程序动态运行过程的描述-PCB(进程控制快)

在linux下是一个task_struct结构体,系统通过这个描述实现对程序运行的管理及调度

四、进程状态

时间片:系统中cpu分时机制,让每一个程序只在cpu上执行一段很短的时间(时间片)

每一个运行中的程序,都应该有一个状态,该状态标记了一个进程该如何被系统进行调度运行

命令:ps -aux | grep loop :

ps -aux  是查看所有进程信息, grep是进行字符串匹配,

|管道符连接俩个命令(将前面命令结果交给后面来处理)

1、linux状态

前台进程&后台进程

前台进程就是指占据了一个终端的进程;

后台进程就是没有关联的进程,默默运行在系统中

下面的状态符号中    R+就表示前台运行态程序

①、运行态--R 正在被执行,以及拿到时间片就能执行的一种状态

②、可中断休眠态--S,一种阻塞态(因为某种运行条件不满足,而暂时不能被调度运行的进程状态,比如sleep(3))

③、不可中断休眠态--D:无法被中断打断阻塞,只能等待阻塞的唤醒条件满足后才能被调度执行

④、停止态--T:什么都不做(这跟休眠不一样,休眠是阻塞,停止还会被调度)

        小明是个植物人,还活着只是什么都不能做

⑤  僵尸态

2、僵尸态

进程退出了,但是资源没有完全被释放,等待处理的一种状态。

僵尸进程:处于僵尸态的进程,是一种退出了,但是资源没有完全被释放的进程

子进程先于父进程退出,然而父进程没有接收到子进程的返回值,所以子进程的资源不能完全释放。

pid_t fork(void):

        通过复制调用进程(父进程)来创建一个新的进程(子进程)

        返回值:在父进程中返回值是子进程的PID(大于0的值);在子进程中返回0,失败返回-1

站在系统角度进程就是pcb,在linux下是一个task_struct结构体

创建了一个进程出来,这个进程叫做子进程,它复制了父进程,里面的大部分数据都是从父进程pcb中复制过来的(内存指针、上下文数据……)

fork创建进程之后,父子进程谁先运行?

        答案:不一定,没有固定顺序,因为进程就是pcb,是系统用于进行程序运行调度管理的描述,相当于系统调度到谁就运行谁

僵尸进程

僵尸进程:子进程先于父进程退出,而父进程没有接收到子进程的返回值,导致子进程无法完全释放资源从而成为僵尸进程

危害:资源泄露(资源没有完全释放)

僵尸进程的避免:进程等待(等待子进程退出,获取退出子进程的返回值,释放子进程的资源,避免产生僵尸进程)

孤儿进程

产生:父进程先于子进程退出,子进程成为孤儿进程

特性:运行在后台,父进程成为1号进程(init进程)

孤儿进程退出后不会成为僵尸进程

孤儿进程没有危害,他会被init进程给接收

 守护进程

一种特殊的孤儿进程

长期运行在后台,不跟任何终端控制相关联

一般操作系统启动时候就启动,关闭的时候就关闭

五、fork()  创建一个子进程

fork函数通过系统调用结构创建了一个与原来进程几乎相同的进程(这个子进程pcb中信息和父进程几乎一致,包括内存指针、上下文数据……),两个进程可以做相同的事儿。

1、返回值

可以利用返回值不同来判断父子进程,进行代码分流,进入不同的分支

在父进程中返回子进程的pid(一个大于0的值)

在子进程中返回0

创建失败返回-1

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int main(){
  5     pid_t fpid;
  6     int count = 0;
  7     fpid = fork();
  8     if(fpid<0)
  9       printf("error in fork");
 10     else if(fpid == 0)
 11     {
 12       printf("i am the child process, my process id is %d", getpid());
 13       printf("我是儿子\n");
 14       count++;
 15     }
 16     else
 17     {
 18       printf("i am the parent process, my process id is %d", getpid());                    
 19       printf("我是爸爸\n");
 20       count++;
 21     }
 22     printf("统计结果是: %d\n", count);
 23     return 0;
 24 }

运行结果:

[dev@localhost fork]$ ./fork5
i am the parent process, my process id is 16866我是爸爸
统计结果是: 1
i am the child process, my process id is 16867我是儿子
统计结果是: 1

分析:

使用fork创建子进程,创建出一个pcb,里面存储的信息和父进程pcb中的信息几乎一致,保留的父进程运行的上下文数据、内存指针……

当创建子进程后,子进程走fpid==0的分支打印我是儿子,打印count为1

父进程走fpid>0的分支,打印我是爸爸,打印count为1

2、创建子进程再认知

    1 #include<stdio.h>
    2 #include<unistd.h>
    3 
    4 int main()
    5 {
    7   printf("hello world\n");
    8   pid_t ret = fork();
    9   printf("it's over!\n");                                                                
   10   return 0;
   11 }

运行结果:

        [dev@localhost fork]$ ./fork1
        hello world
        it's over!
        it's over!

分析

hello world运行一次,而over运行了俩次

当创建子进程之后,子进程pcb中的信息与父进程中的信息几乎一致,(内存指针、上下文数据……)父进程运行到第9行,子进程也保留父进程的运行上下文信息,也运行到第9行,所以父进程与子进程都打印了over代码。

3、创建僵尸进程(滑稽)

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 
  5 int main()
  6 {
  7     pid_t ret = fork();
  8     if(ret < 0){
  9       printf("error fork\n");
 10     }else if(ret == 0){
 11       printf("i am child\n");
 12       exit(0);// 子进程退出
 13     }
 14     else{
 15       printf("i am parent\n");
 16     }
 17     while(1)   // 能走到这里的只有父进程
 18     {
 19       sleep(3);
 20     }
 21     return 0;
 22 }           

上面代码在子进程分支中进行退出,产生僵尸进程,使用下方代码进行查看信息

ps -efl | head -n 1 && ps -efl | grep fork1

 PID 表示进程,PPID的值为父进程的PID,即第二行PID为18126的父进程为18125也就是第一行进程。由于子进程18126先于父进程退出,所以子进程状态为僵尸状态(Z)

 列序号    列含义    列含义说明
1    UID    用户标识ID
2    PID    进程ID
3.    PPID    父进程ID
4    C    CPU占用率
5    STIME    进程开始时间
6    TTY    启动此进程的TTY(终端设备)
7    TIME    此进程运行的总时间
8    CMD    完整的命令名(带启动参数)

 ps命令有一些参数:
-e : 显示所有进程
-f : 全格式
-h : 不显示标题
-l : 长格式
-w : 宽输出
a :显示终端上的所有进程,包括其他用户的进程。
r :只显示正在运行的进程。
u :以用户为主的格式来显示程序状况。
x :显示所有程序,不以终端机来区分。

4、当子进程成为僵尸进程时,父进程退出了!

那么这个子进程还存在吗?

使用kill命令杀死父进程18376

 

程序直接终止了,如果父进程退出了,子进程存在的意义也就没有了。

(子进程就是来给父进程服务的)

5、僵尸进程如何进行处理?

由上一个问题可以知道可以通过kill父进程来关闭僵尸子进程

进行进程等待

6、孤儿进程

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 
  5 int main()
  6 {
  7   printf("hello \n");
  8   pid_t ret = fork();
  9   if(ret < 0){
 10     printf("create error\n");
 11   }else if(ret == 0)
 12   {
 13     printf("i am child\n");
 14   }
 15   else
 16   {
 17     // 父进程先于子进程退出成为孤儿进程
 18     printf("i am parent\n");
 19     exit(0);
 20   }
 21   while(1)
 22   {
 23     sleep(3);                                                                            
 24     printf("i am %d\n",ret);
 25   }
 26   return 0;
 27 }

由下图可见父进程退出后,原来子进程的PPID变成了1号进程,即孤儿18591被1号进程所收养

下图中进程11971为子进程(一般子进程PID大于父进程PID)

它在第一次查看信息时(还没有关闭父进程)显示是S+(S+表示是一个前台进程)

 在第二次查看信息时(关闭父进程后)显示是S(成为了一个后台进程)后台进程的样子就是下方这个状态,不停地在打印  我是子进程这句话

7、孤儿进程退出后会成为僵尸进程嘛?

不会的,僵尸进程是因为在子进程退出时父进程没有接收子进程的返回值,而成为孤儿进程之后,子进程对应的父进程会变为1号进程init,1号进程是个特别负责任的父亲,如果孤儿进程退出了,1号进程会立即关闭它。所以孤儿进程退出不会成为僵尸进程。

六、环境变量

1、概念

所谓变量,就是保存着一个数据,环境变量:保存着当前运行环境参数的变量

2、优点

配置之后即时生效

让运行环境配置更加灵活

通过环境变量可以给运行中的程序传递数据

3、命令env

在终端使用env命令查看当前环境变量

LS_COLOR颜色标记变量

由于环境变量比较多,介绍几个了解就行,下面这个LS_COLORS变量,存储这关于ls命令查看文件颜色的一种变量(颜色标记)什么样的后缀名应该用什么样的颜色来显示

 PATH路径变量

在我们平常一段代码写好,编译之后进行运行的时候,都是在终端上敲入一段路径,比如我在当前路径下touch一个test文件,运行的时候输入 ./test 然而在我们之前的Linux指令中,却不需要这么多表示路径的操作,比如一个ls文件我在任何目录下都可以进行打开,然后查看当前目录文件操作,这就是PATH环境变量的作用,它使得其内部的文件在任何目录下都可以进行运行,PATH变量告诉编译器它里面存储的文件的文件检索地址,所以不需要通过人为的告诉编译器这个文件在哪里。

 4、其他指令

echo ${valuename}        打印指定内容(可以是变量内容)到终端显示

export        声明一个变量为环境变量

set        查看所有变量

unset        删除一个变量

 

 七、环境变量的访问

 1、getenv()接口 :获取用来获取环境变量的值

 

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main()
  5 {
  6     char *ptr = getenv("myvalue");                                                         
  7     {
  8       if(ptr != NULL)
  9         printf("%s\n",ptr);
 10     }
 11     return 0;
 12 }

 !gcc 重新编译上份代码

2、main函数参数

通常的main函数书写都为   int main()

其实它也是有参数的  

int main(int argc, char* argv[], char* env[])

 argc 保存参数个数,argv保存参数名,env参数保存着环境变量

 打印argv运行参数:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main(int argc, char* argv[])
  5 {
  6     for(int i = 0; i < argc; i++)
  7     {
  8       printf("argv[%d]:%s\n", i, argv[i]);
  9     }
 10     return 0;
 11  }                                                                                      

打印env环境变量:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main(int argc, char* argv[], char* env[])
  5 {
  6     for(int i = 0; i < argc; i++)
  7     {
  8       printf("argv[%d]:%s\n", i, argv[i]);
  9     }
 10     for(int i = 0; env[i] != NULL; i++)
 11     {
 12       printf("env[%d]:%s\n",i, env[i]);                                                    
 13     }
 21     return 0;
 22 }

 除了上方的运行参数,还有所有的全局变量

 3、全局变量 extern char **environ;

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main()
  5 {
  6     extern char**environ;
  7     for(int i = 0; environ[i] != NULL; i++)
  8     {
  9       printf("environ[%d]:%s\n",i, environ[i]);                                            
 10     }
 11     return 0;
 12 }

 

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

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

相关文章

vector以及list

之前已经学习过了string类&#xff0c;接下来介绍c中的另外两个类—— vector和list&#xff1b; vector 之前介绍的string类是c所特定的字符数组&#xff1b; 而vector可以看做是string类的扩展&#xff0c;因为它是一个模板类&#xff1b; 它可以作为任何类型的数组&#x…

小侃设计模式(廿二)-访问者模式

1.概述 访问者模式&#xff08;Visitor Pattern&#xff09;指的是在类的内部结构不变的情况下&#xff0c;不同的访问者访问这个对象都会呈现出不同的处理方式。它的主要作用时将数据结构与数据操作分离&#xff0c;将不同的算法与其所作用的对象进行分离。本文将详述访问者模…

DW动手学数据分析Task2:数据清洗及特征处理

文章目录一 数据清洗1 缺失值观察与处理1.1 缺失值观察1.2 缺失值处理2 重复值观察与处理二 特征处理1 分箱&#xff08;离散化&#xff09;处理2 对文本变量进行转换3 从纯文本Name特征里提取出Titles的特征3 参考文章一 数据清洗 数据清洗&#xff1a;我们拿到的数据通常是不…

树的知识概括锦囊(一)

作者&#xff1a;爱塔居 专栏&#xff1a;数据结构 作者简介&#xff1a;大三学生&#xff0c;希望跟大家一起进步&#xff01; 文章目录 目录 文章目录 一、树形结构 二、树的基础知识 三、二叉树 3.1 概念 3.2 特殊的二叉树 ​编辑 3.3 二叉树的性质 四、习题挑战 一、树形结…

手把手教你学51单片机-如何学习单片机

大多数大学生之所以最后变的平庸,不是因为脑子多么笨,也不是全怪自己贪玩不上进,只是没有一个好的领路人,许多学校可能挂着导师的名头,但是多数是挂羊头卖狗肉或者是干脆不管。最后等大学生毕业之后,那些所谓的老师就会说学生很差或者学习很差,反正就是跟自己没啥关系。…

OSPF综合实验(华为)

题目&#xff1a; 思路&#xff1a; 首先配置每个区域的路由和环回地址&#xff0c;其次&#xff0c;根据题目要求打通每个网络的连接&#xff0c;区域0用MGRE打通网络&#xff0c;区域4需要重发布&#xff0c;其次再考虑优化的问题。ip地址的规划是为了更好的路由汇总&#x…

《 Unity Shader 入门精要》第5章 开始 Unity Shader 学习之旅

第5章 开始 Unity Shader 学习之旅 5.2 一个最简单的顶点/片元着色器 顶点/片元着色器的基本结构 // Upgrade NOTE: replaced mul(UNITY_MATRIX_MVP,*) with UnityObjectToClipPos(*)// 定义 shader 的名字 Shader "Chapter 5/Simple Shader" {SubShader{Pass {//…

自动驾驶控制算法之车辆横向控制(project)

本文为深蓝学院-自动驾驶控制与规划-第三章作业 目录 1 projection introduction 2 思路提示 2.1 ComputeControlCmd 2.2 ComputeLateralErrors 3 Corer Case 3.1 Low speed operation 3.2 Extra damping on heading 3.3 Steer into constant radius curve 4 ROSLGSV…

FFmpeg-4.2.4的filter: drawbox源码分析

1. vf_drawbox.c功能 有两个功能 ,添加方框,和添加网格; 1.1 添加方框效果 1.2 添加网格效果

c++数据结构-树(详细总结附代码,一看就懂)

树的定义一棵树是由n&#xff08;n>0&#xff09;个元素组成的有限集合&#xff0c;其中&#xff1a;&#xff08;1&#xff09;每个元素称为结点&#xff08;node&#xff09;&#xff08;2&#xff09;有一个特定的结点&#xff0c;称为根结点或树根&#xff08;root&…

上海亚商投顾:双创指数低开高走,数字经济继续活跃

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪三大指数今日低开高走&#xff0c;创业板指午后涨超1%&#xff0c;科创50指数涨超1.6%。数字经济概念继续爆发&#…

算法基础(一):时间复杂度和空间复杂度

算法基础&#xff08;一&#xff09;&#xff1a;时间复杂度和空间复杂度时间复杂度 O(1)O(1)O(1) O(N)O(N)O(N) O(logN)O(log N)O(logN) O(MN)O(MN)O(MN) O(NlogN)O(Nlog N)O(NlogN)、O(MlogN)O(Mlog N)O(MlogN) O(N2)O(N^2)O(N2)空间复杂度一些算法基础知识点和leetcode题解&…

【网络通信】【电信运营商实战工程师】思科设备篇-思科设备企业网实战

电信运营商实战工程师系列文章. 思科设备篇-思科设备企业网实战. 文章目录1. 思科设备基本开局配置2. ARP协议、交换机工作原理及广播风暴问题3. 思科设备 VLAN 及单臂路由实战4. 思科三层交换机实现 VLAN 间路由实战5. 思科设备静态默认及浮动路由实战6. 思科设备NAT实战全集1…

YOLO_V8训练自己的数据集

YOLO_V8在2023年开年横空出世&#xff0c;在春节前还得卷一下。由于YOLO_V8和YOLO_V5是同一个作者&#xff0c;所以很多操作都是一样的&#xff0c;下面主要描述一下如何用自己的数据集进行训练和测试&#xff08;非命令行的方式&#xff09;。1、训练数据和模型的目录结构这里…

设计模式学习(九):Abstract Factory抽象工厂模式

目录 一、什么是Abstract Factory模式 二、Abstract Factory示例代码 2.1 类之间的关系 2.2 抽象的零件:ltem类 2.3 抽象的零件:Link类 2.4 抽象的零件:Tray类 2.5 抽象的产品: Page类 2.6 抽象的工厂:Factory类 2.7 使用工厂将零件组装称为产品:Main类 2.8 具体的工厂…

linux三剑客之AWK

目录 AWK是什么 AWK基本结构 a.txt的文本实例 AWK内置变量 a.txt的文本实例 AWK自定义变量 a.txt的文本实例 AWK内置函数 a.txt的文本实例 awk高级输出 a.txt的文本实例 排序输出 a.txt的文本实例 条件选择输出 a.txt的文本实例 控制语句 a.txt的文本实例 AWK是什…

Java SE 继承和多态

继承和多态 1. 继承 1.1 为什么需要继承 Java中使用类对现实世界中实体来进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;则可以用来表示现实中的实体&#xff0c;但是 现实世界错综复杂&#xff0c;事物之间可能会存在一些关联&#xff0c;那在设计程序是就需…

Elasticsearch7.8.0版本高级查询—— 指定查询字段查询文档

目录一、初始化文档数据二、指定查询字段查询文档2.1、概述2.2、示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求体内容为&#xff1a; {"name":"张三","…

Git知识学习

主要内容&#xff1a;熟练掌握Git、GitHub、GitLab、Gitee码云的使用 文章目录1.Git概述1.1版本控制1.2版本控制工具1.3Git和代码托管中心2.Git常用命令2.1设置用户签名2.2初始化本地库2.3查看本地库状态2.3.1首次查看2.3.2新增文件2.3.3再次查看2.4添加暂存区2.4.1将工作区文件…

! LaTeX Error: File xxx.sty not found-统一解决办法

在使用一些模板时常见这个错&#xff0c;其实就是缺宏包&#xff01;解决方案如下&#xff01; 第一步&#xff1a;在网站 https://ctan.org/pkg 找到你缺失的宏包&#xff0c;下载zip文件。 第二步&#xff1a;将解压后的文件夹复制到安装路径下&#xff1a; 如&#xff…