Linux进程概念

一、认识冯诺依曼系统:

  • 常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。
    这里写图片描述

截至目前,我们所认识的计算机,都是有一个个的硬件组成
输入单元:键盘,鼠标,扫描仪,写板等
中央处理器:含运算器和控制器

  • 所有的外设都只能和存储器打交道。
  • cpu也只能和存储器打交道。
  • 所以内存起着很重要的作用。

为什么要有存储器?输入设备和输出设备不与cpu直接连接?

cpu运行速度极快,输入设备和输出设备运行速度极慢,存储器介于两者之间。(成指数级别的差距,所以需要存储器来进行缓冲)

为什么程序运行起来必须得先加载到内存里面?

程序运行必须通过cpu调用,cpu只能和内存打交道

二、操作系统:(OS)

任何计算机体系都包含一个基本的程序集合,称之为操作系统
包括

  • 内核(进程管理、内存管理、文件管理、驱动管理)
  • 其他程序(例如函数库,shell程序等)
  • 设计OS的目的:

  • 与硬件交互,管理所有的软硬件资源

  • 为用户程序(应用程序)提供一个良好的执行环境

操作系统是搞管理的,管理者和被管理者并不直接冲突

管理者是通过数据对被管理者进行管理决策

  • 由操作系统提供的接口叫做系统调用
  • 对系统调用进行适度封装,从而形成库
  • 库调用系统,库调用接口在上,系统调用接口在下

这里写图片描述

三、进程

  • 当程序从硬盘外设通过冯诺依曼系统加载到内存,此时程序叫做进程
  • PCB描述进程
    把描述进程的所有信息的那条记录叫做PCB(process control block)

linux下的PCB:task_struct:存放在/usr/src/kernels/2.6.32-431.el6.i686/include/linux/sched.h


这里写图片描述

  1. 优先级:相对于其他进程的优先级。
  2. 程序计数器:程序中即将被执行的下一条指令的地址。
  3. 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块指针。

怎么算这个进程在系统中是否被拿走了?

  • 1、把现在所占用用的资源让了
  • 2、抹掉这个进程的信息

如何删掉一个进程?

  • 进程在内存中主要是 代码和数据 还有信息
  • 1、把代码和数据 还有信息拿掉,2、把对应的pcb拿掉。

windows怎么管理进程?

和linux一样

拓展:

  • 1、硬件中断技术的出现,进而软件片上有了分时系统,时间片轮转。
  • 2、进程:
    从用户角度看:进程是程序的一次动态执行过程。
    从操作系统角度看:
    1)进程是操作系统分配内存,cpu时间片等系统资源的基本单位。
    2)每个进程有自己独立的虚拟地址空间和进程状态。
    3)进程是分配资源的最小单位。
  • 3、程序:为了执行特定任务的一系列指令的有序集合。
  • 4、进程是程序的一次执行过程,需要保存进程的现场信息,这些信息需要一个数据结构来保存,在c语言中用结构体,我们将这个结构称之为PCB(process control block) PCB是操作系统感知一个进程存在的重要数据结构。

  • 5、程序:代码段+数据段
    进程:代码段+数据段+堆栈+PCB
    PCB {
    pc 下一条指令的地址
    esp 栈顶指针
    ebp 基址
    }

6、进程和程序的区别:

   1)进程是动态的,程序是静态的
   2)进程是短暂的,程序是永久的
   3)进程有PCB
   4)一个进程只能对应一个程序,一个程序可以对应多个进程

查看进程:

方法一:
这里写图片描述
方法二:
这里写图片描述
这里写图片描述
这里写图片描述
cwd当前工作目录
exe绝对路径
方法三:
这里写图片描述
方法四:
这里写图片描述

杀死一个进程:

这里写图片描述

查看正在运行时的进程:

这里写图片描述
多次运行后子进程就会发生改变
这里写图片描述
等待进程结束后就查看不到了:
这里写图片描述
这里写图片描述
列出
获取子进程和父进程,多次运行后,发现父进程一直不变,子进程每次都做相应的改变:
这里写图片描述

通过系统调用创建进程-fork初识

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<unistd.h>                                   
  4 int main()
  5 {
  6     int ret=fork();
  7     if(ret<0)
  8     {
  9         perror("fork");
 10         return 1;
 11     }
 12     else if(ret==0)
 13     {
 14         printf("I am child:%d!,ret :%d\n",getpid(),re    t);
 15 
 16     }
 17     else//father
 18     {
 19         printf("I am father:%d!,ret:%d\n",getpid(),re    t);
 20     }
 21     sleep(1);
   }

这里写图片描述

验证了若一个子进程创建成功,父进程会返回一个子进程id,子进程返回0。

进程状态

  • R运行状态:并不意味着进程一定在运行,它表明进程要么是在运行队列里。
  • S睡眠状态:意味着进程在等待事件完成(睡眠也叫可中断睡眠)。
  • D磁盘休眠状态:有时也叫不可中断睡眠状态,在这个状态的进程可以通过发送SIGCONT信号让进程继续运行。
  • X死亡状态:这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

Z-僵尸进程

  • 僵尸状态:当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵尸(死)进程。
  • 僵尸进程会以终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取进程状态,子进程进入Z状态。

查看僵尸进程:

第一个终端:
这里写图片描述
第二个终端:
这里写图片描述
这里写图片描述

僵尸进程危害:

  • 1)子进程一直处于Z状态。
  • 2)Z状态一直不退出,PCB一直都要维护。
  • 3)造成内存资源的浪费。
  • 4)会造成内存泄漏。

孤儿进程:

  • 父进程先退出,子进程就称之为“孤儿进程”

ps axj

这里写图片描述
父进程为1的为孤儿进程

进程优先级

  • 查看系统进程:

这里写图片描述
修改进程优先级的命令:

 - renice:调整已存在进程的nice :renice -5 -9 5200

这里写图片描述
这里写图片描述

 - nice:启动进程前调整nice :nice -n -5 ./a.out

这里写图片描述
用top命令更改已存在进程的nice;
这里写图片描述
这里写图片描述

四、环境变量:

常见的环境变量

  • PATH: 指定命令的搜索路径

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

  • HISTSIZE:指保存历史命令记录的条数
  • SHELL:当前Shell,它的值通常是/bin/bash

查看环境变量方法:

root和普通用户分别执行echo $HOME
- echo $NAME: 你的环境变量名称
这里写图片描述

  • 1、echo:显示某个环境变量值
  • 2、export:设置一个新的环境变量
  • 3、env:显示所有环境变量
  • 4、unset:清除环境变量
  • 5、set:显示本地定义的shell变量和环境变量
    通过代码如何获取环境变量:
  • 命令行第三个参数
#include<stdio.h>
  2 int main(int argc, char *argv[],char* env[])
  3 {
  4     int i=0;
  5     for(;env[i];i++)
  6     {
  7         printf("%s\n",env[i]);
  8     }
  9     return 0;
 10 }             

这里写图片描述
这里写图片描述
通过第三方变量environ获取

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

通过系统调用获取或设置环境变量

  • putenv
  • getenv
    1)设置环境变量: int putenv(const char*str) str的格式:”name=value”
    2)获得环境变量:
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 int main()
  4 {
  5     printf("%s\n",getenv("PATH"));                   
  6     return 0;
  7 }

这里写图片描述
环境变量通常是具有全局属性,可以被子进程继承下去

1 #include<stdio.h>                                    
  2 #include<stdlib.h>
  3 int main()
  4 {
  5     char* env=getenv("MYENV");
  6     if(env)
  7     {
  8         printf("%s\n",env);
  9     }
 10     return 0;
 11 }
  • 环境变量

    定义变量: name=value # 等号左右不能有空格
    删除变量: unset name

  • 1、直接运行出不来结果,说明该环境变量不存在
  • 2、如果只进行MYENV=”hello world”,不调用export导出,不会出现结果
  • 3、导出环境变量 export MYENV=“hello world” ,再运行就出现hello world,说明环境变量是可以被子进程继承下去的
  • 本地变量只能在当前进程使用。
    set:打印更多的变量
    env;只打印环境变量
    export:把普通变量导成环境变量 export name

只要把可执行程序移到/bin目录下,就可以不加./直接运行。

拓展:
1、pstree | grep -A2 -B2 bash 树状打印bash进程的前两行和后两行

这里写图片描述
2、问题:
1)、系统有那些环境变量?
env 命令

2)、将自己定义的环境变量放在哪里? 终端打开就存在该环境变量
登录shell之前,会执行~/.bash_profile 文件,本用户的配置
/etc/profile 整个系统所有 所有用户的配置
这里写图片描述

猜你喜欢

转载自blog.csdn.net/adzn1/article/details/80114277