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 运行父进程 父进程运行30s
 13   else if(id>0)
 14   {
 15     //parent
 16     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     //parent
 16 //    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 arg

void 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("....");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值