• 线程与进程


    目录

    1.为什么使用线程?

    2.什么是线程?

    3.进程和线程的工作原理

    3.1 进程

    3.2 线程

    4.线程安全问题

    5.总结:线程和进程的区别(面试题)


    1.为什么使用线程?

    线程与进程都是用来解决并发编程问题的,而进程自己就可以独立解决并发编程的问题,那么为什么还要引入线程的概念呢?

    因为进程太重了

    创建一个进程,开销较大;销毁一个进程,开销较大;调度一个进程,开销仍较大。

    这样的情况就导致了进程的消耗资源多并且运行速度慢,这显然不是我们的预期。

    而线程相对于进程来说更加轻量,更适合并发编程。

    2.什么是线程?

    了解线程首先要先了解进程,详见《进程的调度》博客,如下。

    http://t.csdn.cn/kpd8T

    在《进程的调度》中描述了进程的概念,一个进程就是一个PCB结构体,但是这样的说法仅限于一个进程中只有一个线程的情况,而一个进程中可以包含多个线程,一个线程对应了一个PCB,这个PCB中的状态、上下文、优先级、记账信息都是各自管理分配的,而同一个进程里面的线程,它们的pid、内存指针和文件描述符表都是相同的,这些属性代表了哪些线程同归属于哪一个进程。

    如果一个进程中有了多个线程,那么每个线程都是在CPU上独立被调用的,也就是:线程是操作系统调度执行的基本单位。

    3.进程和线程的工作原理

    3.1 进程

    比如有一家工厂,这家工厂里面有一个生产车间,一个生产车间对应了一条生产线路,如果这个工厂想要提高自己的收入,那么就需要建立更多的生产车间也就是并发生产,那么如果按照“多进程”区并发,那么则如下图:

    也就是建造多个工厂,每个工厂还是之前的配置,来达到提高生产的目的,但是这样的方法弊端也很明显,就是太浪费空间。

    3.2 线程

     相比于进程的方法,线程只是在同一个工厂里面增加了一个生产车间,不会过多的造成资源的浪费,相比于进程更加轻量。

    但是相比于线程,进程并不是一无是处,因为线程相对于进程来说是不安全的。

    4.线程安全问题

    问题一:线程数量过多

    上面说到,多线程可以减少很多空间的浪费,提高运行速度,那么如果无限制的在一个进程里面去添加线程的数量,会不会让运行速度更快呢?

    如下图:

     可以看到很多人正在对桌子上的100个零件进行拼接,虽然有10个人,但是桌子只能容纳8个人去拼接零件,剩下的两个人如果想去拼接就只能等待别人拼接好了或者将其他人挤到一边,才能开始工作,这样的效率显然不如只有8个人要来得快。

    上述对应的情况:一个CPU上都多个内核,一块内核一次可以执行一个线程,如果在一个进程中线程的数量超出了内核的数量,那么效率并不会因此加快,反而会将开销浪费在线程调度上。

    问题二:线程不安全

     如果两个人同时看上了同一个零件,那么这两个人就可能会因为这一块零件打起来。

    比如:两个线程同时访问同一个变量,就可能出现线程不安全。

    但是多进程就不会出现这种情况,因为各自的都已经分配好了。

    问题三:问题二延伸

     还是问题二的情况,如果有一个人已经将这个零件拿走了,这时另一个人就不开心, 把桌子给砸了。

    比如:一个线程抛出了异常,如果没有处理好,那么整个进程可能就崩溃了。

    5.总结:线程和进程的区别(面试题)

    (1)进程包含线程,一个进程至少包含一个线程,一个进程也可以包含多个线程。

    (2)进程在资源分配和回收上的消耗资源多、速度慢;线程相比于进程更加轻量。

    创建线程比创建进程开销更小;销毁线程比销毁进程开销更小;调度线程比调度进程开销更小。

    (3)进程是系统分配资源的基本单位,线程是系统调度的基本单位。

    (4)在同一个进程的线程之间,共享的是同一块资源,而进程与进程之间的资源是相互隔离开的。

    (5)进程相对于线程更加安全。

    线程与线程之间很容易出现线程安全问题。比如:当多个线程争抢同一个变量时,就可能出现线程安全问题,而这种情况又是容易出现的。

    而线程之间的资源是天然被隔离开的,不容易出现上述的情况,只有在进行进程间通信的时候,多个进程访问同一块资源时,才可能会出现问题。

  • 相关阅读:
    防抖及其优化
    简单自定义MVC优化
    15-bean生命周期,循环依赖
    Rust个人学习笔记2
    无线通信网络
    npm ERR! code ERESOLVE,npm ERR! ERESOLVE unable to resolve dependency tree
    c高级 day1
    Java注解@Transa1ctional失效特殊情况
    Linux替换默认源(yum报错 [Errno 14] curl#7)
    cat()函数和print()函数的区别
  • 原文地址:https://blog.csdn.net/m0_64318128/article/details/128063552