Linux学习之进程

【摘要】要想更好的学习并使用Linux操作系统,学习进程的知识是必不可少的,今天我就把这几天来关于进程的知识总结一下写了一篇博客,希望会对你们有所帮助。

目录:

  • 冯诺依曼体系
  • 操作系统概念与定位
  • 深入理解进程概念,了解PCB
  • 学习进程状态,学会创建进程
  • 了解进程调度,Linux优先级,理解进程竞争性和独立性,理解并发与并行

冯诺依曼体系

冯诺依曼体系总共有四个部分,输入设备,输出设备,存储器和中央处理器
- 输入单元:键盘,鼠标,扫描仪,写板
- 中央处理器:运算器和控制器
- 输出单元:显示器,打印机

  • 存储器指的是内存。不能直接对内存进行操作,必须要通过页表进行映射,这是为了保证数据的安全性。实际上,内存由于速度很快但是空间不大的特点,常常用来作为中间缓存设备。通过内存的虚拟地址空间映射到磁盘的物理空间。

  • CPU只能对内存进行读写,不能访问外设(输入或者输出设备)CPU不能直接去寻找物理内存地址,它只能借助内存的关系来访问物理内存空间。

操作系统

任何计算机系统都包含一个基本的程序集合,操作系统。操作系统包括:
- 内核(进程管理,内存管理,文件管理,驱动管理)
- 其他程序(函数库,shell程序等)

  • 需要说明的是,操作系统是在内核和用户之间管理资源的工具。每次当用户开机的时候,都会加载内核中的启动进程,然后成功启动之后再根据用户的指令去执行其他的操作。shell命令行解释器就是在启动之后自动执行的。
  • 设计操作系统,无非就是为了与硬件进行交互,管理所有的软硬件资源,为客户程序提供一个良好的执行环境。因为客户程序不可能直接和内核去打交道,所以操作系统就可以认为是一个媒介。

  • 计算机管理硬件是先描述起来,然后再管理起来。所谓描述起来,就是用一个结构体将其中的属性和内容放在一起,然后组织起来就是用一个链表或者其他的高效的数据结构将这些结构体串联起来,每当我们需要使用时,就可以根据链表头来查找想要的信息。

系统调用和库函数

  • 操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  • 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以有心得开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层的用户开发者进行二次开发

进程

在这里我需要先说明一下程序和进程的一些不同之处,好方便我们理解进程

  • 程序只是一个存放在磁盘上的可执行文件,其中包含代码段和数据
  • 进程是已经由磁盘加载到内存中的正在执行的程序,它其中包含各种数据,包括PCB(里面放着进程的各种属性文件),还有数据和代码。
  • 进程需要操作系统为其分配资源来运行,程序只是放在磁盘上不会占用CPU资源
描述进程-PCB

每一台电脑上都会有不止一个的进程在运行,因此,为了方便操作系统更好的管理进程,设计者使用了一个进程控制块的数据结构,并把所有的进程信息放在里面,我们可以把它理解为进程属性的集合。
- 在Linux操作系统下的PCB叫做:task_struct

  • 每个进程都具有独立的内存空间和PCB,这样才能保证每个进程之间都不会相互干扰。
  • 当父进程fork出一个子进程时,子进程会拷贝父进程的一切包括PCB,但是,相同的PCB并不表示他们就是同一个进程,因为这里面还有虚拟地址的区别以及内存空间的区别,所以说,PCB相同只能说明两个进程的属性相同,不能说明是同一个。
task_struct内容分类
  • 标识符:描述本进程的唯一标识符,用来区别其它进程
  • 状态:任务状态,退出代码,退出信号等
  • 优先级:相对于其他进程的优先级
  • 程序计数器:程序中即将被执行的下一条指令的地址
  • 内存指针:包括程序代码和进程相关数据的指针,还有其他进程共享的内存块的指针
  • 上下文数据:进程执行时处理器的寄存器中的数据
  • I/O状态信息:包括显式的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
  • 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等
这里面我尤其需要说一下上下文。进程的上下文就是进程当前的运行状态,当一个进程需要进行时间片切换时,操作系统就要把进程的上下文保存在寄存器中方便当时间片下次轮转到该进程时可以正常的运行进程。但是由于进程的属性文件繁多,所以每次上下文切换时都比较消耗时间,这也是进程的一个弊端。为了减少这种问题带来的消耗,就有了后面的多线程,这是一个轻量级的进程,进行上下文切换时要保存的数据也相对更少,性能一定程度上还是优于进程。
进程状态
  • R运行状态:并不意味着进程一定在运行中,它表明进程要么在运行中要么在运行队列中
  • S睡眠状态:意味着进程在等待事件完成(这是可中断睡眠)
  • D磁盘休眠状态:(不可中断睡眠)这个状态的进程通常会等待I/O的结束
  • T停止状态:可以通过发送SIGSTOP信号给进程来停止进程,这个被暂停的进程可以通过发送SIGCONT信号让进程继续执行。
  • X死亡状态:这个状态只是一个返回状态,不会在任务列表中看到这个状态。
几种可能出现的进程
僵尸进程
  • 当进程退出并且父进程(使用wait()系统调用,没有读取到子进程退出的返回代码时就会产生僵尸进程
  • 僵尸进程会以终止状态保存在进程表中,并且会一直等待父进程读取退出状态代码
  • 只要子进程退出,父进程还在运行,但是父进程没有读取子进程状态,子进程就会变成僵尸进程。
#include<stdio.h>
#include<stdlib.h>

int main()
{
  pid_t id = fork();
  if(id < 0){
      perror("fork");
      return 1;
  }
  else if(id > 0){
      printf("parent[%d] is sleeping..\n",getpid());
      sleep(30);
  } else {
      printf("child[%d] is begin z..\n",getpid());
      sleep(5);
      exit(EXIT_SUCCESS);
  }
  return 0;
}

运行结果

僵尸进程的危害
  • 进程的退出状态必须被维持下去,因为他要告诉父进程当它的任务完成时,父进程应该怎样处理接下来的事情,如果父进程一直不读取,那么子进程就一直处于僵尸状态,无法被回收
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在PCB中,那么PCB一直要被维护就需要一直占用资源
  • 如果一个父进程创建了很多子进程,就是不回收,那么就会造成很大的资源浪费。因为数据结构对象本身就占用内存
  • 还会造成内存泄漏
孤儿进程
  • 父进程如果提前退出,那么子进程后退出,进入Z之后,怎么处理?
  • 父进程先退出,子进程就称为“孤儿进程”
  • 孤儿进程被1号init进程领养,当然要有init进程回收
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main()
{
  pid_t id = fork();
  if(id < 0) {
     perror("fork");
     return 1;
  }
  else if(id == 0){
     printf("I am a child,pid:%d\n",getpid());
     sleep(10);
  } else {
     printf("I am parent,pid:%d\n",getpid());
     sleep(3);
     exit(0);
  }
  return 0;
}
进程优先级
  • CPU分配资源的先后顺序,就是进程优先级
  • 优先级高的进程有优先执行权利,配置进程优先权对多任务环境的linux很有用,可以改善系统性能
  • 还可以把进程运行在指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能

查看系统进程 【ps -l】
这里写图片描述

进程其他概念
  • 竞争性:系统进程数目众多,而CPU资源只有少量,甚至一个,所以进程间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便有了优先级
  • 独立性:多个进程运行,需要独享各种资源,进程运行期间互不干扰
  • 并行:多个进程在多个CPU下分别,同时进行运行
  • 并发:多个进程在一个CPU下采用进程切换的方式在一定时间之内,让多个进程都得以推进
环境变量
  • 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 环境变量通常具有某些特殊用途,还有在系统当中具有全局特性
常见环境变量
  • PATH*:指定命令的搜索路径
  • HOME*:指定用户的主工作目录(即用户登录到Linux系统是时的默认目录)
  • HISTSIZE*:指保存历史命令记录的条数
  • SHELL*:当前shell,它的值通常是/bin/bash
查看环境变量 echo $NAME
和环境变量相关的命令
  • echo:显示某个环境变量
  • export:设置一个新的环境变量
  • env:显示所有环境变量
  • unset:清楚环境变量
  • set:显示本地定义的shell变量和环境变量
环境变量的组织方式

每个程序都会有一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串,类似于下面这样
这里写图片描述

总结:关于进程的知识,因为太多了,所以我决定再写一篇博客详细介绍,关于进程,我们对它的理解不能只停留在概念上,应该从深层次去领会,还有关于进程的一些常见函数要熟练使用。
注:本博客如果有什么纰漏,欢迎大家给我指正啊

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值