遇见面试题:进程与线程是什么,他们有什么关系与区别?

83 阅读4分钟

无论是在社招还是在校招面试中,进程、线程都是一个绕不开的问题,在这篇文章中,我们将深入研究在操作系统中进程与线程究竟长什么样子,他们之间又有着什么样的关系与区别。

1、进程是什么

首先我们来看一下进程的定义:

进程就是处于执行期的程序,以及包含的其他资源,如打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,同时还包括用来存放全局变量的数据段等。

从定义中可以看出,进程是处于执行期的程序以及相关的资源的总称。

在Linux系统中,每一个进程都是用一个称为进程描述符(process descriptor)的结构体task_struct来表示,该结构体中包含了一个具体进程的所有信息,例如打开的文件,进程的地址空间,挂起的信号,进程的状态等等。

struct task_struct
{
    unsigned long state;
    int prio;
    unsigned long policy;
    struct task_struct *parent;
    struct list_head tasks;
    pid_t pid;
    ......
}

task_struct结构体可如上段代码所示,在Linux系统中,所有进程的进程描述符都存放在一个叫做任务队列(task list)的双向链表中,调度器通过一定策略在任务队列中选择进程作为当前运行的进程。

接下来,我们看一下进程是如何创建的:在进程创建中,Linux操作系统用到了两个关键的函数:fork()和exec()。进程创建的具体流程如下:

  1. 首先调用fork()函数拷贝当前进程创建一个子进程,子进程与父进程的区别仅在PID(每个进程独有的进程号)和PPID(父进程的进程号)和某些不必要复制的资源。此时子进程与父进程指向相同的地址空间。
  2. 调用exec()函数,读取可执行文件并将其装载进入地址空间开始运行。这一步中,Linux内核会为子进程分配新的地址空间。

2、线程是什么

接下来我们看一下线程又是什么。

线程机制是现代编程技术中常用的一种抽象概念,该机制提供了在同一程序内共享内存地址空间运行的一组线程,这些线程还能共享打开的文件和其他资源。

在Linux操作系统中,其实它并没有线程这个概念。Linux把所有线程都当作进程来处理,所有线程都视作一个与其他进程共享某些资源的进程。 而且每个线程都有一个属于自己的task_struct,因此在Linux内核中,线程看起来就像一个普通的进程,并且内核也没有为线程设计专门的调度机制。

然而,在Windows操作系统中,内核都提供了专门支持线程的机制,并将线程称作轻量级进程,相较于重量级的进程,线程被抽象成了一种耗费较少资源,运行迅速的单元。

3、进程与线程的关系与区别

虽然在Linux系统中,线程与进程在本质上都是由进程描述符表示的,两者仅存在概念上的差别。但在例如Windows的操作系统上线程和进程还是有很大的差别:

1、进程拥有独立的资源,例如每个进程都有属于自己的地址空间。线程通常只拥有属于自己的栈,其他内存空间则可以和其他线程共享。

2、一个进程包含了一个或多个线程,对于系统内核来说,进程是分配资源的最小单位,而线程是运行调度的最小单位。

3、由于进程具有独立的数据空间,进程间的切换会有较大的开销。而同一进程内的线程之间共享代码段和数据空间,线程间切换的开销会小得多。

以上就是进程与线程之间的关系和区别,今天的分享也就结束了,希望大家学有所获、学有所得。