描述线程和进程
描述进程:
进程是分配资源的最小单位,说到进程就不得不提到PCB,在Linux中,描述进程的结构体被称作task_struct(之所以使用结构体,是为了更好地组织大量进程,因为系统中使用链表来存储进程,一个结构体就表示一个进程)。后面我们用PCB中的内容来描述进程,系统中的进程很多,所以我们的进程id就可以区分这些进程,一个进程有数据也有代码,所以需要一个内存指针来管理这些数据和代码,由于进程多但是CPU少,在调度进程时通过进程的优先级确定调用的级别保证正常有序的调度,通过状态可以知道一个进程是在运行状态、睡眠状态、深度睡眠状态、停止状态还是说处于僵死状态。下面从进程的调度来说,如果说一个进程执行到一半被调度走了,那么我们希望他在做完事情后回来还能接着没有执行的位置往下执行,那么就有了上下文数据,记账信息记录了一个进程在在cpu上执行了多久,指令的个数,什么时候从内核下来;最后还有一个很重要的就是文件描述符表,将内核与硬件连接。
描述线程:
线程在Linux下叫轻量级进程,是CPU调度的最小单位,从一个抽象的角度来说,就是进程的一部分,具体用一张图来理解
线程和进程的区别
– | 线程 | 进程 |
---|---|---|
名称 | 轻量级进程(pcb) | (PCB组) |
侧重点 | 执行调度 | 资源分配 |
虚拟地址空间 | 同一个进程中的线程共用一块虚拟地址空间,共用一张文件描述符表 | 进程间虚拟地址空间是独立的,只有vfork()创建出来的进程是共用一个地址空间 |
栈和执行流 | 调用栈各自独立一份(并行执行),独立的执行流 | |
创建 | 利用pthread_create函数创建,创建的线程之间是没有亲缘关系的 | 父进程fork()创建子进程各自是一个独立的执行流 |
终止 | 线程的终止要么要么正常终止,要么异常终止,并不关心返回的结果 | 1、代码执行完,结果正确2、代码执行完结果不正确3、异常终止(信号、exit()) |
等待 | 等待当前进程中的任意线程(阻塞等待),如果不等待会造成内存泄露;不关心等待的返回值时,可以分离线程,当线程退出自动释放资源 | 父进程等待子进程或者等待指定进程(阻塞等待、非阻塞等待),如果不等待会造成内存泄漏,或者是SIGCHLD忽略子进程的退出状态 |
系统开销 | 开销小,多线程共用一份虚拟地址空间避免了拷贝 | 开销大,尤其是当父进程中数据代码很多时,不仅要拷贝,而且子进程另外还要做其他事情 |
调度速率 | 调度快(不需要虚拟地址向物理地址的映射)可以并发执行 | 调度速率慢 |
通信 | (生产者消费者问题)线程可以杀死其他的线程,共用一份虚拟地址空间看到的资源是相同的 | 只有管道、共享内存、信号量、看到同一份资源才能通信 |
线程和进程的联系:
线程异常终止会造成进程异常终止