进程与线程是什么

个人知识库

Author: 刘杰文, Date: 2023-02-08 10:59:00 +0800, Categories: , Tags:

进程与线程是什么

Links:

  1. https://www.zhihu.com/question/25532384
  2. https://www.zhangshilong.cn/work/29436.html
  3. https://www.geeksforgeeks.org/difference-between-process-and-thread/

Mine

进程(Process),线程(Thread)。

至于子进程,那还是个进程,只是具有隶属关系而已,不是在于同一个进程之下,只是逻辑上可能会有控制上的隶属。在实际开发中,也有可能指的是线程而不是进程,看具体情况。辨别是进程还是线程看怎么创建的,进程都是fork()的,线程都是pthread_create()的。

进程和线程其实都是CPU执行时间中的时间段概念,不过进程通常的意义不太一样,是编程语言对其具体实现的隐藏。简单来说,理解成1的比喻是可以的:进程=火车,线程=车厢

事实上,两者的执行都有一个“执行环境”,也叫做“上下文”。所有线程共用进程的上下文,并拥有自己的上下文。在执行时间开销上,也是切换线程上下文的比切换进程的要少的多。

graph TD
切入进程上下文-->执行进程
执行进程-->切出进程上下文
切出进程上下文-->更多进程...
执行进程-.->载入线程上下文
载入线程上下文-.->执行线程
执行线程-.->卸载线程上下文
卸载线程上下文-.->更多线程...
更多线程... -.->切出进程上下文

详细信息见2,具象化比喻见1

img

另外,在Linux系统上有些不一样,Linux系统没有线程,只有进程:

但是,Linux只支持轻量级进程,不支持线程。 在Linux上:

系统启动后的第一个进程是init,其PID为1。 init是系统内核直接运行的唯一进程。 除了init之外,每个进程还有一个父进程(PPID )。 每个进程有四个与用户和组相关联的标识号(real user ID、RUID ) real group ID、RGID有效用户标识号) effect user ID。 EUID )有效的组标识号(effect group ID,EGID ),在Linux内核2.4之前,线程的实现和管理方式完全是通过进程方式实现的。 从2.6版内核开始,可以实现独立的线程。 为了弥补不支持线程的缺点,Linux引入了线程组的概念。 这意味着**该组中**第一个轻量级进程的PID存储在进程描述符的tgid字段中。 getpid ) )系统调用返回当前进程的tgid值而不是pid值。 因此,多线程APP应用程序中的所有线程共享相同的pid。

啊,这不就是把进程打包做了一个分组嘛。。。然后所谓“线程”的进程使用getpid()返回的是tgid,而组内的进程都共用一个pid。所以在linux下,使用getpid()的值关闭的是单独的线程,也就是组内的一个进程,而不会关闭整个线程组,也就是进程。

1

看了一遍排在前面的答案,类似”进程是资源分配的最小单位,线程是CPU调度的最小单位“这样的回答感觉太抽象,都不太容易让人理解。

做个简单的比喻:进程=火车,线程=车厢

作者:知乎用户 链接:https://www.zhihu.com/question/25532384/answer/411179772 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2

这个答案是好多年前写的,当时是在上下班路上的公车上,手机上敲打的,其实很多谬误的地方。文字也很多不准确,有歧义的地方。看到这么多朋友点赞,我尽量修正一下文字,希望更准确的表达我个人的理解吧。 2020年7月30日


不请自来。 看见上面几位的回答我真的是醉了。说几句我的理解。 首先来一句概括的总论:进程和线程都是一个时间段的描述,是CPU工作时间段的描述。是运行中的程序指令的一种描述,这需要与程序中的代码区别开来。

另外注意这里我说的进程线程概念,和编程语言中的API接口对应的进程/线程是有差异的。

下面细说背景: CPU+RAM+各种资源(比如显卡,光驱,键盘,GPS, 等等外设)构成我们的电脑,但是电脑的运行,实际就是CPU和相关寄存器以及RAM之间的事情。

一个最最基础的事实:CPU太快,太快,太快了,寄存器仅仅能够追的上他的脚步,RAM和别的挂在各总线上的设备则难以望其项背。那当多个任务要执行的时候怎么办呢?轮流着来?或者谁优先级高谁来?不管怎么样的策略,一句话就是在CPU看来就是轮流着来。而且因为速度差异,CPU实际的执行时间和等待执行的时间是数量级的差异。比如工作1秒钟,休息一个月。所以多个任务,轮流着来,让CPU不那么无聊,给流逝的时间增加再多一点点的意义。这些任务,在外在表现上就仿佛是同时在执行。

一个必须知道的事实:执行一段程序代码,实现一个功能的过程之前 ,当得到CPU的时候,相关的资源必须也已经就位,就是万事俱备只欠CPU这个东风。所有这些任务都处于就绪队列,然后由操作系统的调度算法,选出某个任务,让CPU来执行。然后就是PC指针指向该任务的代码开始,由CPU开始取指令,然后执行。

这里要引入一个概念:除了CPU以外所有的执行环境,主要是寄存器的一些内容,就构成了的进程的上下文环境。进程的上下文是进程执行的环境。当这个程序执行完了,或者分配给他的CPU时间片用完了,那它就要被切换出去,等待下一次CPU的临幸。在被切换出去做的主要工作就是保存程序上下文,因为这个是下次他被CPU临幸的运行环境,必须保存。

串联起来的事实:前面讲过在CPU看来所有的任务都是一个一个的轮流执行的,具体的轮流方法就是:***先加载进程A的上下文,然后开始执行A,保存进程A的上下文,调入下一个要执行的进程B的进程上下文,然后开始执行B,保存进程B的上下文*。。。*。

*========= 重要的东西出现了======== 进程和线程就是这样的背景出来的*,两个名词不过是对应的CPU时间段的描述,名词就是这样的功能。***

*线程是什么呢? *进程的颗粒度太大,每次的执行都要进行进程上下文的切换。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块组合而成。那么这里具体的执行就可能变成:

程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。

这里a,b,c的执行是共享了A进程的上下文,CPU在执行的时候仅仅切换线程的上下文,而没有进行进程上下文切换的。进程的上下文切换的时间开销是远远大于线程上下文时间的开销。这样就让CPU的有效使用率得到提高。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的CPU时间段。线程主要共享的是进程的地址空间

到此全文结束,再一个总结:

进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。

注意这里描述的进程线程概念和实际代码中所说的进程线程是有区别的。编程语言中的定义方式仅仅是语言的实现方式,是对进程线程概念的物化

作者:zhonyong 链接:https://www.zhihu.com/question/25532384/answer/81152571 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。