text: 进程基本概念、进程地址空间
  强调内容今天来谈一谈进程的一些基本概念，认识一些进程状态，重新认识一下程序地址空间(进程地址空间)，进程调度算法，环境变量等属性。
  程序的一个执行实例，正在执行的程序，是一个担当分配系统资源的实体，系统资源包括CPU时间、内存等。
  2.linux中的PCB 进程信息被放在一个叫做进程控制块(process control block)的数据结构中,存储进程的属性。
  在Linux下，PCB被定义为task_struct，称为文件描述符，它储存在内存(RAM)中。
  3.task_struct 4.可以使用top和ps查看大多数进程信息。
  注: 1)进程id(PID)，获取getpid() 2)父进程id(PPID)，获取getppid() 5.使用fork() fork有两个返回值，父子进程代码共享，数据各自开辟空间，采用写时拷贝，私有一份。
  先执行父进程，在执行子进程6.进程状态 1)R(running):运行状态，要么在运行，要么在运行队列里。
  2)S(sleeping):进程在等待事件完成，也叫做可中断睡眠。
  3)D(disk sleep):磁盘休眠状态，也叫做不可中断睡眠，这个状态经常会等待IO的结束。
  4)T(stopped):可以发送SIGSTOP信号使进程停止。
  这个暂停的状态可以发送SIGCONT使进程继续运行。
  6)Z(zombie):僵尸状态
  7.僵尸进程 1)概念:当进程退出并且父进程没有读取到子进程退出的返回代码时，就会产生僵尸进程。
  所以只要进程退出，父进程还在运行，没有读取子进程的状态，子进程就进入僵尸状态。
  2)一些说明: a.子进程变为僵尸状态，它就需要一直被维持下去，因为父进程必须知道子进程的事办的怎么样了，办完了，还是没有办完,还是异常退出，只要父进程没有读取，子进程就一直处于僵尸进程。
  b.僵尸状态也需要task_struct保存进程基本信息。
  c.当父进程一直不读取很多子进程，这个内存资源就会被占用，有可能会发生内存泄漏。
  #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>main()
  {ret=fork();创建子进程(ret<){
  perror("fork");return;
  }else(ret==){//childprintf(,getpid(),ret);sleep();exit(EXIT_SUCCESS);子进程五秒后正常退出
  }else{printf(,getpid(),ret);sleep();
  }注: A.查看子进程状态时，可以使用ps aux | grep a.out查看，是静态查看。
  -p 指定某些个PID来进程查看监测而已。
  因此，孤儿进程并没有危害。
  #include <stdio.h>#include <unistd.h>#include <stdlib.h>main()
  {ret=fork();(ret<){
  }else(ret==){printf(,getpid(),ret);sleep();
  }else{printf(,getpid(),ret);sleep();exit(EXIT_SUCCESS);
  } 1.概念:CPU资源分配的先后顺序，合理地配置进程优先权，可以提高系统的性能。
  PID:进程ID号。
  PPID:这个进程由哪个进程衍生而来，即父进程。
  PRI:进程执行的优先级，值越小越早被执行 NI:代表这个进程的nice值。
  进程可被执行的优先级的修正数值，RPI(new)=RPI(old)+nice, 所以当nice值为负数时，优先级会变高，所以调整nice值，就可以改变进程的优先级，nice的取值范围为-20到19，共40个级别。
  3.独立性 多进程运行，需要独享各种资源，多进程运行期间互不干扰。
  如果时间到，进程还没有被执行完，CPU将被切走去执行其他的进程，如果未到时间，进程却阻塞了，CPU会立即被切走，当一个进程的时间片走完，它就会被移到队列的末尾。
  b.先来先服务 根据先后顺序执行进程，但是会产生饥饿现象，所以短作业不适合。
  c.优先级调度算法 在进程队列中选择优先级最高的来执行。
  d.多级反馈队列 将时间片轮转与优先级调度相结合，把进程按优先级分成不同的队列，可以兼顾长短作业，适用很多场景。
  e.高响应比优先调度算法。
  HOME:指定用户的主工作目录。
  SHELL:当前shell,它的值通常是/bin/bash 注:查看它，echo $NAME 3.相关命令 1)echo:显示某个环境变量的值 2)export:设置一个新的环境变量 3)env:显示所有的环境变量 4)unset:清除环境变量 5)set:显示本地定义的shell变量和环境变量 注 a.命令行第三个参数可以获取环境变量 1.父子进程代码共享，数据各自开辟空间，采用写时拷贝私有一份#include <stdio.h>#include <sys/types.h>#include <unistd.h>okc=;main()
  }else(ret==){
  okc=;printf(,getpid(),okc,&okc);子进程先退出，修改了okc的值
  }else{sleep();printf(,getpid(),okc,&okc);
  }通过程序验证，发现其父子进程虽然地址相同，但是地址中的内容却不相同，说明该地址绝对不是物理地址，在linux中，地址被称为虚拟地址，C中看到的都是虚拟地址，物理地址用户是看不到的，物理地址由操作系统统一管理。
  操作系统可以将虚拟地址转换为物理地址。
  运用虚拟地址内存，可以更好的管理内存空间，保护了内存，每个进程认为自己都独享物理内存。
  2.运行程序 运行一个程序，需要先将程序加载到内存中，早起的内存分配机制，进程地址空间不隔离，由于程序都是直接访问物理内存，恶意程序就可以随意修改别的进程的代码，从而破坏其他程序。
  所以把物理地址暴露给进程会带来很严重的问题。
  但并不是所有的“程序”都运行在物理地址的。
  内核在初始化页表之前并不使用虚拟地址，而是直接使用物理地址。
  2)页表:其存放在物理地址空间中，系统为每个进程建立了一张页面映像表，进行地址映射。