linux入门进程概念中(僵尸进程,孤儿进程,进程优先级,并行和并发,环境变量)

目录

一、进程状态

1.看看Linux Kernel怎么说

1.1阻塞

2.进程状态查看

3.僵尸进程

3.1模拟僵尸进程的实验

 3.2僵尸进程的危害

4.孤儿进程

4.1模拟孤儿进程实验

二、进程优先级

三、环境变量

3.1常见环境变量

3.2查看环境变量的方法:

3.3 加入环境变量

3.4 获取环境变量

四、命令行参数

 


一、进程状态

1.看看Linux Kernel怎么说

     为了弄明白正在工作的进程是什么意思,需要标注进程的不同状态。一个进程有几个状态(在linux内核中,进程也叫做任务)

1.1阻塞

进程等待某种资源就绪,而导致不被推进的状态。从冯诺依曼体系结构上理解,比如现在在电脑的软件管家上下载东西,但是由于网络原因下载中断。os会让下载进程在运行队列里排队,等待网卡恢复正常,在网卡设备后面排队,等待网卡资源。这个过程称为阻塞。即进程在其他设备队列中排队

 

  • R(running),R状态并不一定是进程在cpu运行,而表示该进程在运行队列中排队。

  • S(Sleep),可中断休眠,是阻塞状态的一种。进程等待休眠完成。比如现在使用printf函数在显示器上打印,由于cpu的速度远远大于访问外设的速度,打印需要等待cpu资源。或者使用scanf输入,还没输入的时候,等待键盘数据,这个时候就是在等待键盘资源

  • D(Disk Sleep),不可中端休眠,在这个状态进程通常会等待IO结束。无法被kill,出现这种状态一般是cpu调度进程由内存往磁盘中写入数据,磁盘快满了就会导致很卡,此时若关机,会导致数据丢失。可能会导致宕机

  • T(Stopped),可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。在断点处停下,就是一种暂停状态

  • X死亡状态(dead),这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

2.进程状态查看

命令:ps axj  / ps aux

想要一直观察某个进程的状态,使用方法如下:

while :;do ps aux |grep test |grep -v grep; sleep 1 ; done //隔一秒打印一次test进程的状态

3.僵尸进程

如果一个进程退出了,立马X状态,作为父进程没有机会拿到子进程的退出结果。所以在Linux中,一般进程不会立即退出,而是要维持一个状态叫做Z,也叫做僵尸状态,方便后续父进程读取该子进程的退出结果。可以使用实验来模拟僵尸状态:fork一个子进程,让子进程先退出,但是不要回收子进程。

  • 僵尸状态,是一个比较特殊的状态,当进程退出并且父进程没有读取到子进程退出的状态返回码,子进程就会产生僵尸状态。
  • 僵尸状态会以终止状态保持在进程列表中,并且会一直等待父进程读取退出状态码
  • 所以只要子进程退出,父进程还在运行,但是父进程没有读取子进程状态,子进程就进入Z状态。

3.1模拟僵尸进程的实验

        写一段代码,让父进程运行30s,子进程运行5s,此时子进程先退出,父进程还在运行,同时父进程没有获取到子进程的退出码,子进程进入僵尸状态。代码如下:

  1 #include <stdio.h>2 #include <stdlib.h>3 #include<unistd.h>4 5 int main()6 {7   pid_t id = fork();//创建失败8   if(id<0)9   {10     perror("fork");                                                                             11     return 1;12   }// id >0 运行父进程 父进程运行30s13   else if(id>0)14   {15     //parent16     printf("parent[%d] is sleeping ...\n",getpid());17     sleep(30);18 19   }// id == 0 运行子进程, 子进程运行 5s 20   else {21     printf("child[%d] is begin Z ...\n",getpid());22     sleep(5);23     exit(EXIT_SUCCESS);24   }25   return 0;26 }27 

同时 使用命令查看进程的状态如下:

 3.2僵尸进程的危害

  • 进程的退出状态必须被维持下去,因为它要告诉它的父进程,你交给我的任务,我办的怎么样了,可是父进程一直不读取,那么进程就处于Z状态
  • 维护退出状态本身就是使用数据维护,属于进程的基本信息,所以要保存在tast_struct(PCB)中,Z状态一直不退出,PCB就需要一直维护
  • 那么,一个父进程创建了很多子进程,但是不回收,就会造成资源的浪费,因为数据结构对象本身就要占用内存,就比如C语言中定义一个结构体变量,就需要在内存的某个位置进行开辟空间
  • 内存泄露

4.孤儿进程

  • 父进程如果提前退出,子进程后退出,进入Z状态之后,应该如何处理?
  • 父进程先退出,子进程就称为孤儿进程
  • 此时,子进程被1号进程init领养,由init进程回收

4.1模拟孤儿进程实验

写一段代码,让子进程运行10s,父进程运行3s,此时父进程先退出,子进程由1号进程收养。

 #include <stdio.h>2 #include <stdlib.h>3 #include<unistd.h>4 5 int main()6 {7   pid_t id = fork();8   if(id<0)9   {10     perror("fork");11     return 1;12   }13   else if(id ==0)14   {15     //parent16 //    printf("parent[%d] is sleeping ...\n",getpid());17     printf("I am child ,pid:%d\n",getpid());18     sleep(10);19 20   }21 22   else {23     // parent 24     printf("I am parent,pid:%d",getpid());25     sleep(3);26   }27   return 0;28 }29                    

实验现象如下:

二、进程优先级

  • CPU资源分配的先后顺序,就是指进程的优先权
  • 优先权高的进程有优先执行权利,配置进程优先权对多任务环境的linux很有用,可以改善系统性能
  • 还可以把进程运行到指定的cpu上,这样一来,把不重要的进程安排到某个cpu,可以大大改善系统性能

三、环境变量

环境变量本质上是一个内存级的一张表,这张表在用户登录系统的时候,进行给特定用户形成属于自己的环境变量表。

环境变量中的每个都有自己的用途,有的是进行路径查找,有的是进行身份认证,有的是动态库查找的,有的是用来确认当前路径等等,每个环境变量都有自己的特定应用场景。

每一个元素都是kv的

环境变量的数据由系统相关配置文件中读取进来的 .bashrc  .bashprofile(bashprofile调用.bashrc)

make编译完程序之后,我们通常要使用./运行程序,带./就是相对路径,定位到当前的可执行程序

  • 环境变量一般是指在os中用来指定os运行环境的一些参数
  • 如我们在编写c/c++代码的时候,在链接的时候,从来不知道我们所链接的动静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就有相关的环境变量帮助编译器进行查找
  • 环境变量通常具有某些特殊用途,还在系统中通常具有全局属性

3.1常见环境变量

PATH 指定命令的搜索路径

HOME:指定用户的主工作目录(即用户登录到Linux系统中时,默认的目录)

SHELL:当前shell,它的路径通常是/bin/bash

3.2查看环境变量的方法:

echo $Name //Name 要查的环境变量的名称

3.3 加入环境变量

a. export PATH = 要添加的路径,此时直接运行,发现只有当下路径的文件可以运行

b. export PATH = $PATH:要添加的路径 这种方法就是把当前路径拷贝到环境变量下

在linux中,把可执行程序拷贝到系统的默认路径下,让我们可以直接访问,这种就相当于在linux下软件的安装,删除路径就相当于卸载

在代码 int main(int argc, char * argv[ ], char * envp[ ] ) 这三个形参中,char * envp是环境变量表,是一个指针数组,里面存放着char * 类型的地址,比如:" /a/b/c:",如下图:前若干个指向有效地址,最后一个指向NULL

 

3.4 获取环境变量

a.通过命令行参数获取

#include<stdio.h>int main(int argc , char * argv[], char * envp[])
{int i = 0;//提取特定的地址,最后一个为null就不执行for(;envp[i];i++){printf("%s\n",envp[i]);}return 0 ;}

b.通过第三方变量environ获取

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以使用的时候要用extern声明

#include <stdio.h>int main(int argc, char * argv[])
{//全局变量extern char ** environ;int i = 0;for(;environ[i];i++){printf("%s\n",environ[i]);}return 0;
}

通过函数获取环境变量getenv,getenv("要获取的环境变量")

#inlcude<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main()
{char * user = getenv("USER");if(user == NULL)perror("getenv");else printf("USER:%s\n",user);return 0;
}
#inlcude<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main()
{char * user = getenv("PWD");if(user == NULL)perror("getpwd");else printf("PWD:%s\n",user);return 0;
}export PATH = $PATH: 路径 
可以在命令行直接执行

我们现在已经知道了进程内部已经有了环境变量,所以我们可以这样使用,通过strcpm来判断当前用户是谁,如果不是本人,就不能执行当前文件

#define NAME  "abc"
int main()
{char * own = getenv("USER");if(strcmp(own,NAME) == 0){printf("这个程序已经执行了");}else{printf("%s非法执行 ",own);}}

shell读取命令和命令行,echo export (不带export变量也可以被shell记住,但是没有在环境变量表中存放,这种叫做本地变量)自定义一个变量myval,然后shell就会在环境变量表中malloc一个64位的空间,把myval存放进去,可以使用env查看

环境变量可以被子进程继承,环境变量具有全局属性

四、命令行参数

通过输入不同的参数,就可以执行不同的程序

int main(int argc,char*argv[ ])
{for(int i = 0; i<argc,;i++){printf("agrv[%d]->%s\n",i,argv[i])}
}在命令行中输入 ./mytest -a -b -c -d   ./mytest 可执行程序
-a -b -c -d 参数选项  argv[] 中 0号下标指向可执行程序 1号 1号子串  2号 2号子串
argc 代表命令行参数的个数
// .myproc argvoid Usage(const char * name)
{printf("\nUsage:%s -[a|b|c]\n,name);exit(0);  //终止进程
}int main(int argc,char *argv[])
{if(argc !=2)Usage(argv[0]);if(strcmp(argv[1], "-a" == 0)printf("打印当前目录下的文件名");else(strcmp(agrv[1] ,"-b" ==0)printf("....");
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA开发与运维(怎么通过docker部署微服务jar包)

目标&#xff1a; 通过docker的方式部署微服务。 一、背景&#xff1a; 我们通过java开发的微服务可以打成jar包&#xff0c;我们可以直接通过裸机部署&#xff0c;也可以通过docker来部署&#xff0c;本文介绍通过docker来部署微服务。 二、首先我们介绍一下docker的发展过程…

LLM应用的技术栈与设计模式详解

大型语言模型是构建软件的强大新原语。 但由于它们是如此新&#xff0c;并且其行为与普通计算资源如此不同&#xff0c;因此如何使用它们并不总是显而易见的。 在这篇文章中&#xff0c;我们将分享新兴 LLM 应用程序的参考架构。 它展示了我们所见过的人工智能初创公司和先进科…

七牛云面试复盘-实习后端Java开发 一面复盘 【已通过】

💪💪💪欢迎订阅本专栏,持续更新,本专栏内容为我参加的各个公司面试的复盘专栏。将完整记录面试细节问题。 七牛云面试 实习后端Java开发 一面 [视频面试] 首先自我介绍 我是XXX,来自XXX,XXXX。 面试官提问: 1.先问几个基础题,循序渐进的来哈,谈谈Java⾃动装箱…

【云原生】软件架构的演进以及各个架构的优缺点

文章目录 1. 什么是软件架构?2. 单机架构3. 应用数据分离架构4. 应用服务集群架构5. 读写分离架构6. 冷热分离架构7.垂直分库架构8. 微服务架构9. 容器编排架构10. 小结 1. 什么是软件架构? 软件架构是指在设计和构建软件系统时&#xff0c;对系统的组织结构、组件、模块、接…

【大数据之Hive】十九、Hive之文件格式和压缩

1 Hadoop压缩概述 Hive中的压缩算法与Hadoop中的压缩算法保持一致&#xff0c;可以把Hive当作Hadoop的一个客户端。 【大数据之Hadoop】十八、MapReduce之压缩 2 Hive文件格式 Hive表中常用的数据存储格式&#xff1a;text file&#xff08;行式存储&#xff09;、orc&#x…

Java中操作文件(一)

目录 一、引入 二、File概述 2.1、属性 2.2、构造方法 2.3、方法 2.4、代码示例 示例1 示例2 示例3 示例4 示例5 示例6 示例7 示例8 一、引入 文件是操作系统中的重要概念&#xff0c;Java作为一个跨平台语言&#xff0c;可以针对不同的操作系统处理文件。…

linux下查看cpu使用率和内存占用

top top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示系统中各个进程的资源占用状况&#xff0c;类似于Windows的任务管理器&#xff0c;下面详细介绍它的使用方法&#xff1b; top是一个动态显示过程&#xff0c;即可通过用户按键来不断刷新当前状态。如果在前台…

【Android】解决 build项目报错manifest merge fail XXX

报错图片&#xff1a; 解决方式&#xff1a; 找到 AndroidManifest.xml文件&#xff0c;找到找到文件的上一级&#xff0c;加上android:exported“true” 作用&#xff1a;Android:exported true 在Activity中该属性用来标示:当前Activity是否可以被另一个Application的组件启…

Mybatis 核心分析

一、Mybatis 整体执行流程 二、MyBatis的整体架构体系 三、详情 概述&#xff1a;对应 session 模块。 接口层相对简单&#xff0c;其核心是 SqlSession 接口&#xff0c;该接口中定义了 MyBatis 暴露给应用程序调用的 API&#xff0c;也就是上层应用与 MyBatis 交互的桥梁。接…

增强深度学习与对抗训练对癫痫发作的鲁棒预测

标题&#xff1a;Augmenting Deep Learning with Adversarial Training for Robust Prediction of Epilepsy Seizures Abstract: 癫痫是一种慢性疾病&#xff0c;涉及异常的大脑活动&#xff0c;导致患者失去对意识或运动活动的控制。因此&#xff0c;在癫痫发作之前检测出癫…

使用TIA博途自带的函数实现用户登录并显示用户名的具体方法

使用TIA博途自带的函数实现用户登录并显示用户名的具体方法 本例以TP1200 Comfort精智触摸屏为例进行说明: 如下图所示,打开TIA博途软件,添加一个TP1200触摸屏,找到左侧项目树中的“用户管理”,添加一个用户:abc,密码:1234, 如下图所示,添加一个画面,这里命名为:…

12.JavaWeb-Node.js

1.Node.js的概念 传统的Web服务器中&#xff0c;每个请求都会创建一个线程&#xff0c;这会导致线程数的增加&#xff0c;从而影响服务器的性能和扩展性&#xff0c;Ryan Dahl借助Chrome的V8引擎提供的能力实现了Node.js——可以在服务端运行的JavaScript&#xff08;可以把Nod…