linux中的进程、环境变量和虚拟地址
目录
- 冯诺依曼体系结构
- 操作系统
- 进程概念
- 程序和进程
- 什么是程序
- 什么是进程
- 查看进程信息
- 进程、进程标识符&进程状态
- 进程创建
- 僵尸状态和僵尸进程
- 孤儿进程
- 环境变量
- 定义
- 常见的环境变量
- 查看环境变量
- 设置环境变量
- 临时生效
- 永久生效
- 为什么需要加$[环境变量名]?
- 环境变量的代码验证
- 从main 函数的参数中获取
- 通过 getenv 函数获取特定环境变量的值
- 通过environ参数进行获取
- 进程虚拟地址空间
冯诺依曼体系结构
1、数据存储在“内存”当中
2、计算机中的数据一切皆二进制
冯诺依曼体系机构提出的数据架构图:
数据由输入设备输入,再由内存将数据提交给CPU进行处理,再返回内存通过输出设备输出
操作系统
操作系统是软件,操作系统在管理计算机的软硬件资源
管理 = 描述 ( 自定义数据类型 ( struct ) ) + 组织 (链表 )
操作系统 = 操作系统内核 + 应用
系统调用接口 ( 函数 ) :操作系统为程序员提供的函数,程序调用这些函数可以使用操作系统管理的资源
库函数:一帮程序员将难用的系统调用接口重新封装了一遍
如何区分一个函数是库函数还是系统调用函数?
man [函数名称]:左上角如果是2,则是系统调用函数,左上角是3,则是库函数
进程概念
程序和进程
什么是程序
程序就是经过源代码编译出来的文件,这个文件是静态的
什么是进程
进程就是程序运行时的实例,是动态的,从内核的角度来看,进程是操作系统分配资源的实体
查看进程信息
使用 ps aux 命令可查看所有进程信息
在 ps aux 后添加 | grep ./程序名可查看特定进程
进程、进程标识符&进程状态
进程标识符(PID):在操作系统中唯一标志一个进程
进程状态
并行:多个进程在同一时刻拥有不同的CPU进行运算,称之为并行并发:多个进程在同一时刻只能由一个进程拥有CPU进行运算,称之为并发
大的方面来说:就绪,运行,阻塞
细分的角度来说:
R:运行状态S:可中断睡眠状态D:不可中断睡眠状态T:暂停状态ctrl + z:使得一个程序变成暂停状态,但此时进程是存在的,并不等同于ctrl + c
如果需要恢复至运行状态需要输入 fg 后回车t:跟踪状态,在进行gdb调试时会出现X(ctrl+x):死亡状态 Z:僵尸进程
程序计数器:保存了进程即将要运行的下一条指令
上下文信息:保存了寄存器当中的内容
内存指针:指向了程序地址空间
记账信息:使用CPU的时长,占用内存大小
IO信息:保存了当前进程打开文件的信息
/proc:保存了当前操作系统维护的所有进程信息,每一个进程都是一个文件夹
进程创建
1、getpid()函数:获取当前进程的pid号,谁调用获取谁的
2、geippid()函数:获取当前进程的父进程的pid号,谁调用获取谁的父进程
随后 ./test
现在就得到了父进程和当前进程的pid号
现在让他们不停止
此时我想知道是什么启动了这个进程
可以发现启动这个进程是是 -bash ,也就是命令行解释器
这也意味着这个进程的父进程其实就是bash
fork函数:可以让程序员在代码中创建一个子进程
pid_t fork(void);1、没有参数2、pit_t:本质是整形3、含义:
查看进程发现有两个进程
此时需要区分一下谁是父进程谁是子进程
这样就不仅显示了当前进程,同时也在当前进程的pid后生成了父进程的pid号
黄标为当前进程,蓝标为父进程
返回值:创建子进程失败:返回-1创建成功:①:>0 返回给父进程②:==0 返回给子进程大于0的值本质是子进程的PID号原理:fork创建的子进程的PCB拷贝父进程的PCB
僵尸状态和僵尸进程
更改一下刚才的fork代码
父进程先创建子进程,随后走 else 逻辑,在执行打印后开始执行sleep;
子进程被创建后走 else if 逻辑,执行打印后跳出,最后 return;
执行后全打印出来
再看看刚才的 child 的 pid 号
看到后边显示进程状态为Z,代表为僵尸进程
僵尸进程的产生由来:子进程先于父进程退出,子进程在退出的时候,会告知父进程,父进程没有来得及回收子进程的资源,导致子进程的PCB没有被释放
kill 命令:kill + [ pid ],可以杀死一个进程
试着杀死刚才的僵尸进程
发现僵尸进程依旧存在
kill 第二个指令:kill -9 [ pid ],为强杀,对进程的杀伤力更强
此时发现依然无法杀除僵尸进程
僵尸进程的危害:子进程的PCB没办法得到释放,相当于内存泄漏了
怎么解决?
1、重启操作系统,代价大,不推荐
2、kill 父进程,僵尸进程就不存在了
这样发现父进程和僵尸进程一起不见了
代价相对较大,不推荐
3、进程等待,推荐的方式,优雅的方式
孤儿进程
再次更改 fork
这次让父进程先结束,子进程不结束
1 号进程是启动时操作系统创建的第一个进程,这也意味着刚才创建的子进程在回收时是由 1 号进程来进行回收的
孤儿进程:
1、父进程先于子进程退出,子进程会被 1 号进程所领养,子进程在退出到时候,就会由 1 号进程回收子进程的退出资源,从而子进程就不会变成僵尸进程,称这样的进程为孤儿进程
2、进程状态当中没有一个状态称之为孤儿状态,但是有进程被称为孤儿进程
环境变量
定义
环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
常见的环境变量
PATH:保存了可执行程序的搜索路径
在其中有个重要的间隔符“:”,在:前后都是路径,代表了搜索时所经过的路径
SHELL:保存了命令行解释器的名称
HOME:保存了当前用户的家目录
查看环境变量
echo $[ 环境变量名 ]
env 可以查看操作系统中所有的环境变量
设置环境变量
固定范式:export [ 环境变量名称 ] = $[ 环境变量名 ]:[ 新增加的路径 ]
临时生效
如果直接使用fork会发现此时无法找到fork指令
设置后发现PATH里边已经存在了fork的路径,再次使用fork
但是当克隆一个终端时,fork便无法使用
这就是临时生效,即将export执行在了命令行当中,只在当前终端中生效
永久生效
~/.bashrc 或者 ~/.bash_profile:环境变量文件当新打开一个终端的时候,就会读取环境变量文件当中的内容
接着打开文件
或者
在其中都能看到export命令
可以创建一个新的环境变量
创建后用 source 命令来通知系统重新读取这个文件
再查看,已经创建成功了
接着拷贝终端试试
发现也可以使用,代表这是永久生效,即写到环境变量文件中,每次启动终端的时候,都会被加载
为什么需要加$[环境变量名]?
拿PATH来实验一下吧
正常的PATH里边有这些
如果光这么写
可以发现里边只剩下了一个路径
此时再ls
哦豁,没有找到这个命令,因为全被删除掉了
环境变量的代码验证
从main 函数的参数中获取
首先写一个程序
试着输入命令
此时会输出多少个命令?或者说我们实际上向程序内输入了多少个命令?
三个?
其实是四个,即 命令参数的个数也将可执行程序也计算在内
而在程序中,我们可以将传递进去的命令预先设置一个动作,而在程序接收到这个命令后便会做出反应
再执行程序,发现程序在发现输入 -a 时便退出了
再试一下换个顺序
看来是实现了依据输入的指令做出预设的动作
同样我们可以命令行参数来获取环境变量
char* env[]:组织格式
永远都在数组的最后一个元素存放一个NULL指针
此时 ./main 一下
发现拿到了很多的环境变量,和之前的 查看环境变量 中的 env 命令是一样的
通过 getenv 函数获取特定环境变量的值
char *getnev(const char *name)
参数:
name:环境变量名称
返回值:环境变量的值
例如“PATH” ==> getenv(“PATH”)
返回值就是:
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/stealth/.local/bin:/home/stealth/bin
怎么验证?
编写一串代码,使用 getenv 来输出PATH的环境变量的值
得到输出
通过对比一致
通过environ参数进行获取
environ:参数是C库当中定义的,程序员如果要使用,可以使用 extern 关键字进行使用,类型是:char**
试着用 extern 关键字调用 enviorn 输出环境变量
同样输出成功了
进程虚拟地址空间
写一串代码
运行一下,不出所料的输出了同样的数值
此时让他们取地址
发现他们的地址是一样的
更改一下代码,在子进程中将 g_val 更改为100
再运行一下
发现在同一个地址,却有不一样的数据?
这就是虚拟地址,每一个进程在启动的时候都会被分配一个空间,但这个空间是虚拟出来的,并不能直接保存数据
程序员在代码当中看到的地址并不是真正的物理内存地址,而是操作系统内核虚拟出来的地址,虚拟地址并不能保存数据,保存数据是物理内存在保存
意义:进程虚拟地址空间,构成了进程的独立性,一个进程修改数据,不会影响另外一个进程
linux中的进程、环境变量和虚拟地址相关推荐
- 如何在Linux中配置JDK环境变量
如何在Linux中配置JDK环境变量 目录 如何在Linux中配置JDK环境变量 一.下载JDK 二.配置环境变量 三.刷新配置 一.下载JDK Java Downloads | Oracle 得到安 ...
- 【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级
文章目录 1. 孤儿进程 2. 环境变量 1. PATH环境变量 证明ls是系统指令 修改自己写的可执行程序对应路径 2. env--查看系统环境变量 3. 获取环境变量 envp environ g ...
- Linux中修改PATH环境变量(只在当前窗口下生效)
前言,要执行oracle中的一个命令sqlldr 在oracle的bin目录下,使用sqlldr命令时,显示 -bash:sqlldr: command not found 但是直接在根目录下 /us ...
- linux中perl的环境变量,在Perl脚本中使用Bash环境变量?
小编典典 这里有两个查询,关于使用Bash变量和运行外部命令. Perl中有%ENV哈希,带有环境变量 perl -wE'say $ENV{PWD}' 但是,通常最好在脚本中使用等效项,因为脚本的含义 ...
- linux中的c 环境变量,Linux C 参考手册 之 环境变量篇
getenv(取得环境变量内容) 相关函数 putenv,setenv,unsetenv 表头文件 #include 定义函数 char * getenv(const char *name); 函数说 ...
- Linux中常见的环境变量笔记
1.变量:BASH Bash Shell的全路径 比如:echo $BASH 2.变量:BASH_VERSION Bash Shell的版本号 3.变量:EUID 记录当前用户的UID.root用户值 ...
- linux中配置jmeter环境变量,linux java 和jmeter 环境变量配置文件笔记(原)
我在EC2 亚马逊的ubuntu系统下进行的配置,步骤如下(非常简单) 1.在/usr/local下分别新建java和jmeter文件夹,把下载的包进行解压 注:此处有坑,需注意ll -lht 查看 ...
- linux系统默认的环境变量path,Linux编程 12 (默认shell环境变量, PATH变量重要讲解)...
一 .概述 默认情况下, bash shell会用一些特定的环境变量来定义系统的环境.这些默认环境变量可以理解是上篇所讲的系统全局环境变量. 1.1 bash shell支持的Bourne变量 Bo ...
- 《Linux C编程从入门到精通》》一2.4 Linux中的调试环境gdb
本节书摘来自异步社区<<Linux C编程从入门到精通>>一书中的第2章,第2.4节,作者 宋磊 , 程钢,更多章节内容可以访问云栖社区"异步社区"公众号查 ...
最新文章
- vue中解决Uncaught ReferenceError: regeneratorRuntime is not defined问题
- 【杂谈】提升写代码效率不得不做的三件事
- batocera_手把手教你安装batocera系统,把旧电脑变成万能影音游戏主机
- daterangepicker 日期范围插件自定义 可选 年份
- kotlin半生对象_Kotlin程序| 随播对象特征
- 30条架构原则:助你成为大牛架构师
- lucene 增量 全量 更新索引_10年+,阿里沉淀出怎样的搜索引擎?
- ACL 2021 | PENS: 个性化新闻标题生成数据集
- Javascript获取日期和星期
- c语言变量名由啥组成,一个c语言是由什么构成
- GDAL插值使用示例
- bzoj 1009: [HNOI2008]GT考试(dp+kmp+矩阵快速幂)
- sql server 安装时提示要重启
- 三次握手与accept()函数
- Httpd总结 :HTTPD的基本概念
- paip.lucene 4.3 中文语义搜索最佳实践
- tps5430应用电路详解_详解常用电阻的优缺点
- linux安装mysql_Linux学习笔记-安装MySQL
- 一切皆是文件:UNIX,Linux 操作系統的設計哲學
- Spring中init-method和destroy-method的四种方式
热门文章
- pandas添加、修改dataframe中index的列名
- C# 入门笔记(脚本)
- 怎样让计算机快速开机,怎样设置可以让电脑快速启动开机.doc
- c 直接访问mysql_C语言访问MySQL数据库的方法
- 微服务 数据库耦合_mysql – 与其他服务共享的微服务数据库
- BUU OJ 做题记录
- Spring 7大功能模块的作用[转]
- bzoj 4596: [Shoi2016]黑暗前的幻想乡
- Qt入门(8)——事件和事件过滤器
- 带头结点的单链表的初始化,建立,插入,查找,删除