洛阳网站建设找汉狮,长春城乡建设部网站首页,武昌区建设局网站,注册公司需要花多少钱Linux环境变量孤儿进程进程优先级其他概念环境变量感性的理解环境变量常见的环境变量添加环境变量环境变量的组织形式通过代码如何获取环境变量再次理解环境变量命令行参数孤儿进程 概念:父进程先于子进程结束#xff0c;这样的子进程就叫做“孤儿进程”#xff1b; “孤儿”…
Linux环境变量孤儿进程进程优先级其他概念环境变量感性的理解环境变量常见的环境变量添加环境变量环境变量的组织形式通过代码如何获取环境变量再次理解环境变量命令行参数孤儿进程 概念:父进程先于子进程结束这样的子进程就叫做“孤儿进程” “孤儿”进程真的就没有了父进程了吗 答案是当然不是当子进程原先的父进程先子进程一步“去”过后会由os启动领养程序该子进程会被init进程也就是os领养此时init进程就是子进程的父进程 那么为什么孤儿进程需要被init领养呢 回答这个问题也就是回答如果不领养孤儿进程会怎么样 如果没有进程领养孤儿进程的话在孤儿进程结束后由于没有父进程接受它的状态码也就是没有父进程对其所占的空间进行回收孤儿进程就会一直处于“僵尸”状态白白的浪费内存造成内存泄漏为此为了回收孤儿进程结束过后的空间os就安排自己充当了孤儿进程的父进程 下面我们通过一段代码来演示孤儿进程 #includestdio.h #includeunistd.hint main(){pid_t idfork();if(id0){//childwhile(1){printf(我是子进程,我的pid:%d,我的ppid:%d\n,getpid(),getppid());sleep(1);}}else if(id0){//fatherint sec10;while(sec){printf(我是父进程,我的pid:%d,我的ppid:%d,我还有%ds死去!\n,getpid(),getppid(),sec--);sleep(1);}}else{printf(error!\n);}return 0;}
我们可以通过利用ps -axj命令来查看我们进程的pid和ppid 此时子进程由原来的前台程序变为了后台程序我们可以通过ps命令输出的STAT哪一项来判断状态带号的就是前台程序不带号的就是后台程序我们利用Ctrlc的快捷键杀不死后台程序但是我们可以利用命令kill -9 pid或者killall 进程名这两个命令来杀死进程
进程优先级 什么是进程优先级就是那个进程先执行那么进程后执行 为什么会有进程优先级 因为CPU资源有限为了使每个进程都合理的使用到CPU资源 怎么使用优先级? 首先我们可以通过命令:ps -al来查看 其中修改优先级的公式:PRIPRI(默认值)nice; nice的取值范围:[-20,19]; nice值为什么是这个区间因为一个进程的优先级必须有个度不能过高也不能过低过高或过低都会严重造成CPU资源的分配不合理 如何修改优先级 我们可以输入top命令-输入r-输入进程pid-输入nice值; 一般情况下我们普通用户只能把优先级变大不能把优先级变小如果想要变小优先级我们可以切换成root 如果想要变小优先级的话需要切换成root因为普通用户权限不够 其他概念 竞争性: 系统进程数目众多而CPU资源只有少量甚至1个所以进程之间是具有竞争属性的。为了高效完成任务更合理竞争相关资源便具有了优先级. 独立性: 多进程运行需要独享各种资源多进程运行期间互不干扰. 并行: 多个进程在多个CPU下分别同时进行运行这称之为并行. 并发: 多个进程在一个CPU下采用进程切换的方式在一段时间之内让多个进程都得以推进称之为并发. 环境变量 概念环境变量environment variables一般是指在操作系统中用来指定操作系统运行环境的一些参数 说实话这官方的概念我们初学者理解起来比较困难我来说说我对于这句话的理解吧 我认为环境变量就是指定os在一些特定情况下该做什么的动态参数 就比如os应该把临时文件放在哪里当我们运行一个程序时并没有指定该程序的位置时os应该去哪里寻找这个程序在我们需要读取当前机器的用户名时os应该去哪里拿 我们可以通过设置环境变量来告诉os遇到这些情况时应该去哪里寻找“答案” 感性的理解环境变量
或许上面的一通概念并没有让我们理解什么是环境变量下面我们通过一个例子来更好的理解环境变量 在Linux环境下为什么在运行我们自己的可执行程序时需要带上./这样的相对路径或者绝对路径而在运行诸如:ls、cd、tree、cp等命令时不需要带上它们的路径我们可不可以让自己的程序也能不带上路径就运行起来呢 首先当我们在运行一个不带任何路径的程序时os会去PATH环境变量下寻找是否含有当前程序找到了就执行找不到就报错而对于我们指定路径的程序则去指定路径下搜索 那么PATH环境变量里面到底装的是什么 我们可以通过命令echo $PATH来查看PATH环境变量下的内容 我们可以发现PATH里面都是一些路径这些路径以:作为分隔 那么我们如何让我们自己的程序像ls等命令一样不用指定路径也能直接使用呢 如果我们想要想要像:ls、pwd、tree等命令一样使用起来不带路径的话我么只需要将我们的可执行程序添加到PTAH中任一一条目录下或者将我们的路径追加到PATH环境变量下面 首先我们来实验一下第一种办法 1、将我们的可执行程序添加到PATH环境变量下的任意一路径中去比如我们可以将我们都程序添加到PATH下的/usr/bin/目录下去 当然如果我们还是按照原来的方式./Code2-22来运行程序也是可以的 2、直接将我们当前目录添加到PATH环境变量中去 首先我们先来演示一种错误的添加方式 PATH路径 向上面这种添加方法虽然我们的程序可以不带路径运行了但是像ls这些命令就不能运行了想要运行他们必须带上路径了 可这终归不是万全之策在后续的使用上极其不方便这里主要有两个解决办法 1、将原来PATH默认的路径重新赋值给PATH 2、重新登录shell就可以了 既然上面的那种赋值方式不是正确的方式那么该如何向PATH环境变量里面追加路径呢 PATH$PATH:路径 像这样过后我们不仅可以不带路径的使用我们追加的路径下的可执行程序同时也不会影响ls等命令的使用 常见的环境变量
通过上面的例子我们对于环境变量有了一定的理解接下来我们来看一看一些比较常见的环境变量 PATH : 指定命令的搜索路径 HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录) SHELL : 当前Shell,它的值通常是/bin/bash。 USER:当前登录机器的用户 PWD当前所在目录 当然这都是一些比较常见的环境变量我们如果想要查看所有环境变量的话我们可以使用命令env 添加环境变量
那么如何添加环境变量 我们可以通过命令export 环境变量我们也可以给这个环境变量赋值export 环境变量100
环境变量的组织形式
首先我们知道环境变量是存储的有内容的那么这些环境变量里面的内容是从哪里来的 答环境变量的内容一般是由os从特定的配置文件中读取到的当我们的os启动完毕过后os就会读取相关配置文件里面的数据放到环境变量里面在Linux下环境变量一般都在家目录下的.bashrc和.bash_profile; 这些环境变量也是数据os也会对这些数据进行管理os利用一个字符指针数组来维护这个环境变量表 每个程序都会收到一张环境表环境表是一个字符指针数组每个指针指向一个以’\0’结尾的环境字符串 这个环境变量表的最后一个元素是NULL以此来表示环境表的长度;
通过代码如何获取环境变量
通过代码环境变量主要有3种方式 1、通过main函数的参数获取 我们都知道main函数是可以带参数的而且最多可以带3个参数比如 int main(int argc,char*argv[],char*envp[]); 其中envp就是指向这个环境表的首元素指针通过envp我们可以获取到环境变量 下面我们通过代码测试 2、我们也可以不用main的参数C语言给我们提供了一个全局的字符指针用来指向环境表我们也可以通过这个全局的环境表来访问环境变量这个全局的字符指针也就是environ我们只需要声明一下即可使用 3、通过getenv函数来获取 上面的两种方法虽然可行但是用起来实在是不方便比如我向访问一下USER这个环境变量还得我自己去写匹配算法去一个一个寻找很是麻烦而是用getenv函数则会省去我们自己写匹配算法查找的过程我们只需要告诉getenv我们需要获取哪个环境变量即可getenv就会返回对应环境变量的内容如果没有找到对应环境变量则返回NULL 接着我们利用getenv来测试一下 的确是这样的为此我们可以利用该函数实现一个只允许ikun使用的pwd命令 测试代码 为了保持我们的pwd指令能像系统的pwd指令那样执行我们需要将我们的代码所形成的可执行程序添加到PATH其中一个默认目录下 接着我们来使用一下自己的pwd 再次理解环境变量
环境变量就是内存级的一张环境变量表这张表由用户登录的时候os根据用户形成用户自己环境变量表每个用户的环境变量表都不一样 环境变量表中的每个元素都有自己的作用和应用场景有的是用来进行查看当前用户名的有的是用来进行用户查找的有的用来记录当前路径的等等…… 每一个环境变量都有自己的应用场景 那么如何理解环境变量是一张内存级的表呢 你说一个int a10double b20这样的a、b变量我能理解那么环境变量为什么说是内存级 在os启动的时候os会启动shell程序然后将自己读取到的环境变量交给shell当我们在命令行输入export MYPATH1000shell会认为你是在定义一个新的环境变量然后shell就会去内存找块空间将MYPATH1000这个字符串存起来或者malloc一块空间让后将该空间的指针添加到环境变量表里面这样就完成了新增环境变量环境变量是可以被子进程继承下去的而我们启动的程序都是shell的子进程因此我们的进程是可以拿到shell维护的环境变量表的 同时我们需要注意一下export定义的环境变量具有全局性也就是export定义的环境变量是会进入环境变量表的也就可以被所有子进程访问但是没有用export定义的环境变量是不具有全局性的这种环境变量不会进入环境表自然也就无法被子进程访问只能在Shell本身进程访问 比如我们现在创建一个本地的环境变量我们的子进程是访问不到的 我们再来通过我们的程序获取该变量 我们的Code2-22作为shell的子进程并没有在从shell上继承下来的环境表中访问到MYPATH 同时我们也可以通过命令env来验证该命令env只会显示出全局的环境变量对于本地环境变量不显示 我们发现依旧没有结果 当时我们用set命令来找到我们设置的本地环境变量set命令会显示出全局的和本地的环境变量 如果我们想要清除环境变量的值可以用unset命令 命令行参数
上面我们再介绍利用代码获取环境变量的时候提到了可以利用main函数的参数来获取其中我们介绍了envp参数但是argc、argv参数没怎么讲现在我们就来理解一下这两个参数的意义 int main(int argc,char*argv[],char*envp[]),从结构上我们可以看到argv与envp是同一个类型于是我们可以大胆的猜测一下argv也可能表示的是一张表其中argc是这个表的长度 那么这个表里面有什么呢我们可以打印出来看看 我们可以发现argv似乎输出的是们在命令行输入的指令我们命令行输入的什么argv就输出什么 我们现在来剖析一下我们在命令行输入的东西 你看这和我们ls -a -l 的形式是不是一样的实际上我们在命令行指令选项的方式时shell会读取到这一串字符串然后以空格作为间隔将指令和选项存在一张表里面当Shell为我们的指令创建进程的时候就会将这张表传给子进程子进程就可以根据选项表现出不同的功能 因此argv的作用就是可以让我们的程序根据不同的选项执行不同的功能