写给小白看的线程和进程,高手勿入

系统 Linux
进程和线程都是计算机操作系统中的基本概念,在进程和线程之上有程序,应用程序是具有某种功能的程序,运行在操作系统中。

 计算机的核心是CPU,它承担了计算机的所有计算任务,CPU就像一个工厂,时刻在运行着,而操作系统管理着计算机,负责任务的调度、资源的分配和管理。

[[337221]]

图片来源于网络

进程和线程都是计算机操作系统中的基本概念,在进程和线程之上有程序,应用程序是具有某种功能的程序,运行在操作系统中。

例如,我们的桌面上都会安装QQ、酷狗音乐、微信......等,这些就是程序。当我们点击QQ运行时,QQ正常运行,此时就会开启一个进程。

因此,「程序是静态的,而进程是动态的,程序是作为进程的运行的载体,进程会随时间,会在某一时刻消亡。」

图片来源于网络

我们运行程序开启的进程,我们可以在任务管理器中可以查看,当我们再次点击QQ,登陆另一个账号的时候又会开启一个进程。

打个比喻:前面我们把CPU比作一个工厂,那么程序就好像工厂里面的车间。

[[337222]]

图片来源于网络

但是,车间是静态的,车间中有多条流水线,进程就好比流水线,流水线是动态执行的,一个车间可以同时运行多条流水线,也可以只执行一条流水线或者一条流水线都不执行。

总结来说:「程序可以包含多个进程,多个进程并发执行,相互独立,因此,进程也是系统进行资源分配和调度基本单位。」

当然,程序也可以没有启动进程,就好比车间中没有流水线,因为程序是静态的,而进程的有无就好比层间的流水线是否存在。

[[337223]]

图片来源于网络

一条流水线上可以有很多工人,那些工人就好比是线程,一个员工就代表一个线程,他们在一起共同协作,完成一条流水线上的任务。

[[337224]]

图片来源于网络

所以,「进程与线程的关系是包含关系,一个进程中至少有一个线程,或者多个线程,一个线程只能归属于一个进程中」。就好比一个车间中可以有多个流水线,一条流水线上有多个功能开工,在组长安排下工人只能在一条流水线上工作。

图片来源于网络

当然,进程中的所有线程共享这该进程的所有资源,比如:内存空间,每个线程都可以使用这个内存空间。就好比车间中的空间都是各条流水线共享的。

[[337225]]

不同的空间若能容纳的工人也不一样,就好比厕所一次只能一个人进厕所,当后面来的人,注意到厕所门已经关闭,就知道里面有人,就只能等候前一个人用完,他才能用。

厕所里面的人,为了防止他人再次进入厕所,就会把厕所锁住,这就是「互斥锁(Mutual exclusion,缩写 Mutex)」,这就意味着在进程中的某一些空间一次只能由一条线程使用。

[[337226]]

图片来源于网络

有些空间就会比较大,一次可以供多个人使用,比如:休息室,休息室的座位都是有限的,一次只能供20的座位休息,其余的人就坐不下了。

[[337227]]

用于标识这个空间仅给20个人使用的办法就是给每个座位打一个编号1-20,每进去一个人就给这个人发一个作为编号,当编号用完了,表示这个空间已经满了。

[[337228]]

图片来源于网络

当有人出来了就会把编号还给看守的那个人,便是又有空间可以使用了,这个做法就是「信号量」,这样保证了每个人都有自己的座位,即保证多线程不会相互冲突。

「那为什么有进程还要多线程呢?」 每个进程都有自己独自的代码和数据空间,即为「程序的上下文」,进程包含多个线程,进程的切换消耗要大于线程的切换消耗。

图片来源于网络

线程可以看作是轻量级的进程,每个线程也有自己的「运行栈」和「程序计数器(PC)」、以及「线程的本地存储」,所以对于进程数比较多的,频繁的切换进程将会带来一大笔的开销,反而线程的切换开销小。

图片来源于网络

进程是一个「动态」的概念,进程包含下面的五种状态:「初始态,执行态,等待状态,就绪状态,终止状态」。

图片来源于网络

线程中的状态也是包含下面的五种:「新建(NEW)、可运行(Runnable)、运行(Running)、阻塞(BLOCKED)、死亡(DEAD)」。

图片来源于网络

那么进程之间是怎么交互的呢?在进程之间的通信包括「管道、系统IPC(包括消息队列,信号量,共享存储), SOCKET。」

管道的方式由包括以下三种方式:

  1.  「普通管道」PIPE:通常会有限制,可能是半双工方式,或者是只能在子父进程中使用。
  2.  「流管道」s_pipe:可以使用双向传输。
  3.  「命名管道」name_pipe:它允许可以在不相关的进程之中使用。

线程之间的通信在JMM模型中是通过共享内存来实现的,例如:线程一要和线程二通信,线程一先把自己的变量副本写入主内存中,然后线程二再从主内存中读取该变量,复制到自己的线程空间中进行操作,线程都不能直接操作主内存。

 

为了保证多线程之间的数据一致性的问题,可以使用锁机制,实现线程之间的操作的同步、有序。例如:「synchronized锁、Lock锁、Atomic原子类」。

单线程时代,一次只能执行一个任务,后面的任务只能排队等候,实现的方式都是串行化的,随着后续的发展为了提高效率,实现了多线程。

单CPU的多线程方式,实现的是并发方式,并发真正意义上的并行,因为CPU一次只能执行一次任务,但是,CPU的执行速度远快于线程的执行速度,为了充分利用CPU,因此实现并发的多线程方式。

图片来源于网络

多CPU时代的来领,实现真正意义上的并行多线程,同一时刻可以由多个线程的执行。

图片来源于网络

最后总结:「操作系统中是以多进程的形式执行,以多线程的方式执行,允许讲单个任务由多个部分执行,并且在多线程之间能够提供协调机制,允许进程之间、线程之间有共享的部分,又能够保证进程之间、线程之间不会相互影响」。 

 

责任编辑:庞桂玉 来源: Linux学习
相关推荐

2021-01-28 09:58:46

线程池线程Thread

2021-06-25 07:37:33

递归函数算法

2020-03-03 15:17:40

进程线程调度

2015-12-08 11:39:59

JavaScript引擎指南

2022-05-18 09:31:42

编译器开源代码生成

2020-08-06 08:05:13

云计算

2024-09-09 18:36:57

2019-01-15 09:00:27

人工智能AIML

2010-12-03 11:14:58

IT人

2023-04-27 07:43:22

RabbitMQ重试队列死信队列

2017-07-26 16:15:17

Python案例入门级

2019-02-26 11:15:25

进程多线程多进程

2018-10-23 16:40:08

Python编程语言实用案例

2009-10-28 10:01:57

2021-06-11 11:28:22

多线程fork单线程

2021-04-20 12:39:52

Node.js多线程多进程

2021-08-04 23:30:28

Node.js开发线程

2020-10-12 08:32:34

浏览器进程线程

2022-10-12 09:01:52

Linux内核线程

2010-07-26 09:45:09

Perl多进程
点赞
收藏

51CTO技术栈公众号