基础概念

进程

进程是程序在某一数据集上的一次运行活动,是系统进行资源分配和调度的进本单位,由以下组成

分配给他的内存地址空间
安全属性
线程
进程状态

进程的特性

  • 动态性:进程是程序的一次执行过程,是动态的
  • 并发性:进程可以和别的进程一起并发执行
  • 独立性:进程是能够独立运行的基本单位,也是系统执行资源分配和调度的独立单位
  • 异步性:由于进程间的相互制约,进程的执行是间断性的。
  • 结构:进程由程序、数据、进程控制块组成
  • 同个程序可以在不同的数据集上构成不同的进程得到不同的结果,但是在执行过程中程序不能发生改变

进程的状态转化

avatar

就绪:进程已经被分配到出了CPU以外所有的资源,等到获取到了就可以立即执行

执行:进程正在运行中

阻塞:正在执行的进程,由于某些条件不满足无法继续执行,于是放弃CPU处于阻塞状态

进程的切换

同步和异步

同步指一个任务的完成必须要依赖另外一个任务的时候,得等到那个被依赖的任务完成后,这个任务才能完成,要么都成功,要么都失败,两个任务的状态可以保持一致

异步指任务通知完被依赖的任务需要做什么工作后,这个任务不需要等待他,而是继续自己执行,只要自己这个任务完成就算完成了,所以异步是不可靠的序列

阻塞和非阻塞

阻塞是指运行中的进程(线程)在获得想要的结果之前,这个进程(线程)会被挂起

非阻塞指调用无法立即获得想要结果时,也不会阻塞该进程

异步操作也是可以被阻塞的,只不过他是在等待消息通知的时候被阻塞,而不是处理消息的时候被阻塞

并行与并发

并行指两者同时进行

并发指资源有限的情况下,两者交替轮流使用资源

死锁

指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程

进程类型

守护进程:与终端无关,由系统引导启动

前台进程:与终端有关

生命周期

https://www.cnblogs.com/zhangchao0515/p/5339964.html

linux中创建一个新进程的方式是使用fork函数,fork()执行一次有两个返回值,在父进程中返回值是子进程的进程号,在子进程中返回值是0

使用fork函数得到的子进程是父进程的一个复制品,它从父进程处复制了整个进程的地址空间,包括进程上下文,进程堆栈,内存信息,打开的文件描述符,信号控制设定,进程优先级,进程组号,当前工作目录,根目录,资源限制,控制终端等。而子进程所独有的只是它的进程号,资源使用和计时器等

父进程fork复制自己的地址空间创建子进程,每个子进程分配一个PID,PID和父进程的PID是子进程环境的元素,所有进程都可以创建子进程,所有进程都由初始进程创建

子进程继承父进程的安全性身份、过去和当前的文件描述符、端口和资源特权、环境变量,以及程序代码,随后子进程自己运行,通常父进程在子进程运行期间处于睡眠状态,当子进程完成发出信息退出,父进程接收子进程的信号被唤醒。子进程在退出时丢弃资源环境,其余部分称为僵尸,父进程被唤醒后清理剩余结构并继续执行自己的代码

初始进程

centos5/6:init
centos7:systemd

linux主要以四种方式创建新的进程

  • 系统初始化(前台进程负责和用户交互,后台进程与用户武馆,运行在后台并且直在需要时才唤醒的进程叫做守护进程)
  • 进程在运行中开启子进程
  • 用户的交互式请求而创建一个新进程(双击打开某exe)
  • 一个批处理作业的初始化

    进程状态

    每个CPU核心同时只能处理一个进程,在进程运行时,随着资源分配情况不同,他也会处于不同的状态

R运行状态:进程要么在运行要么在运行队列

S睡眠状态/可中断睡眠:进程在等待事件的完成

D磁盘睡眠状态/不可中断睡眠:等待IO结束

T停止状态:可通过发送SIGSTOP信号给进程来停止进程,等接收到SIGCNT信号继续运行

Z僵尸状态:通知父进程回收资源

僵尸进程:当一个子进程退出后,如果父进程没有利用wait或者waitpid来获取子进程的状态信息,那么子进程的状态描述符依旧保存在系统中

孤儿进程:如果父进程突然被中止,子进程就成为孤儿进程,将被初始进程接管

X死亡状态:这是一个返回状态,不会出现在任务列表

线程

线程是进程中最小的执行单位

这句话是什么意思?

就比如说,我们打开任务管理器,里面能看到很多进程,我们双击打开一个qq,那也是一个进程,这个运行着的qq他有很多功能,比如说看天气,群消息,好友消息等等,我们可以在看天气的时候,同时去看好友消息,他们不是同一个功能,但是执行起来不需要等一个结束了才能去执行另外一个,这个就叫多线程,再更具体一点,比如说看下面这段代码

avatar

这里提供了一个work函数,下面采用了两种调用方式:一种是多线程,一种是多进程他们的区别在于。多进程,p1和p2每一个都分配到了一份空间资源等,他们在自己各自的那份资源里面运行work,而多线程模式下,主进程拥有t1,t2两个线程,主进程占有一份资源,t1和t2不另外再去外面获取资源,而是在主进程的那份当中获取一部分来执行work。

多进程与多线程的优缺点

多进程可以使用多个内核,可以通过增加CPU来提升性能,另外可以减少线程加锁/解锁对性能的影响,每个进程互相独立,子进程崩溃也不会影响主程序的稳定性,理论上来说多进程好像会多耗很多资源,但是在linux里面,linux采用写时拷贝,可以节省一定的资源,当一个变量x在父进程中存在,父进程在创建多个子进程的时候,子进程不会每个都把这个x复制一遍,而是和父进程采用同一个内存空间的变量,当子或父进程需要改变x的值的时候,才会复制这个变量,这样父子之间变量互不影响,父子进程地址空间完全隔开,但是变量的地址可以完全相同。多进程和多线程两者开销没有显著区别,而多进程的性能明显要好于多线程

多进程具有封闭性和可再现性,多道程序设计实现了程序的并发执行和资源贡献,提高了系统效率和资源利用率

多进程的控制逻辑较为复杂,需要和主程序交互、跨进程边界,如果有大量数据传送就不太好

多进程和多线程的优缺点

在Linux下编程多用多进程编程少用多线程编程。

多线程无需跨进程边界,程序逻辑和控制比较简单,线程可以共享内存和变量等,消耗的总资源比进程少点,操作系统切换线程比在切换进程速度上要快得多。多线程一般用于IO密集型的任务

多线程比起多进程,会存在一些安全隐患,当多线程处理同一个共享变量的时候,可能A刚把这个数读出来,B对其进行了减一操作,而A不变,这样会导致数值上出现问题.为了防止这个问题我们可以对这个变量加锁,当一个对象给锁住了的时候,如果别的线程想要获取这个对象,必须等锁他的线程执行完释放后才可以,否则一直处于等待状态

多线程一个挂全完蛋,进程则互不影响

什么是多线程?如何实现多线程?

协程

协程是一种用户态的轻量级线程,由用户自己控制调度,一个线程可以拥有多个协程.一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协助运行,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。常用的如python的yield,await等

标签: none

评论已关闭