zoukankan      html  css  js  c++  java
  • 操作系统基础梳理--进程&线程

    1、举个栗子

    1.1、知乎一形象例子


    【摘自知乎】比如说十几年前,马化腾在写QQ,假设他那个时候不懂多进程多线程。然后他就开始写啦,这玩意儿不简单吗,不就是用户输入什么,把信息打包发到另一个用户,再显示出来,卧槽,太简单,2天就能写完一个字符界面的qq!
    然后想当然的写出如下伪代码:

    while(1):
    wait for user input
    send user input by UDP/TCP
    display incoming messages
    end while
    

     这个代码很简单,就是不断地查询用户的输入情况,然后把输的东西发给对方,然后把对方发过来的信息显示到屏幕上。

     这么简单,如果当年有python,QQ一天就能发布了。马化腾可开心了,然后就开始调试了。他队友发了一条信息过来,马化腾就在自己电脑面前等啊。。。等啊。。。等啊。。。。丫,怎么还么有信息显示出来啊?猪队友啊?小学生啊?会不会打字啊?呆逼啊,又要单步调试啊?马化腾就开始单步调试了,然后他发现自己的程序卡在了wait for user input上一直不动!对,程序一直在等待输入,如果不输入的话,是没有办法执行后面的任务的!
     那怎么办?要不默认如果用户在1秒以内不输入,就跳过input阶段,直接进入后面接收和显示?那也不行,这样会有一定的几率丢失用户输入信息,大爷的!!!
     这个时候你就会发现,如果能把输入和显示这两个任务分开,变成两个“程序”,那就太好了。好,那就分成两个程序吧,一个负责输入和发送信息,一个负责读入信息和显示。卧槽,真是太天才了!说干就干!要不了多长时间,两个窗口就诞生了,瞬间觉得自己好牛逼啊!
     这个时候,所用的实现方式就是我们说的多进程。这样的方式会产生很多问题,比如:马哥突然发现多开几个聊天窗口的话,会把内存给压榨干净。。。。两个窗口之间交换数据会很麻烦,得走系统层面才能解决。。。。等等等等
     这是为什么呢?盖因为多进程的程序,每一个进程都有自己的独立内存空间和资源,相互都是保密的,这就造成了进程之间通信需要通过系统才能完成,无疑会造成资源浪费和时间浪费。

     那怎么办?就不能让两个“程序”共享同一片内存空间,他们自己之间交换数据而不通过系统吗?

    这时,你才需要一个线程的概念,这就是线程的意义。在一个进程当中,任务需要同时“运行”,不能互相干扰,但是有一些变量,内存,信息之类的又要共享,这才需要到线程。

    2、Oracle在不同OS种的进程&线程 区别


     Oracle的Unix/Linux版本采用多进程架构,不同的功能模块由不同的进程负责,Windows版本采用单进程多线程架构,所有的模块所在线程处在同一个进程当中。

     我们来看一下区别:

    1. 进程管理。Oracle某个模块挂起了,没有响应,万般无奈你要重起这个模块,Unix平台只要重起这个模块所在的那个进程就可以了,其它进程保持运行,而Windows平台只有一个进程,只能影响所有模块,重启过程中所有模块都不能提供服务。
    2. 内存空间。每个进程拥有自己的地址空间,如果只有一个进程,所有模块共享/约束在同一空间,如果采用多进程,所有进程地址空间独立,软件申请/管理更多内存的可能和能力变大了。Unix/Linux环境很多运行在小型机,甚至大型机上,单进程显然满足不了需求,Windows运行在PC主机上,对这个没什么要求。
    3. 线程间通信。因为单进程共享地址空间,进程内线程通信效率很高,不同进程的线程之间通信需要某种IPC手段,效率相比降低。其实Linux平台没有传统意义的“线程”,所有都是进程,我们看到的进程是一个进程组,里面的“线程”就是组成这个进程组的进程。
    4. 资源管理。单进程中其中一个线程操作文件句柄阻塞了,会影响到其它线程对这个句柄的操作,多进程无此问题。一个进程同时打开的句柄是受限制的,多进程意味着可使用更多资源。
    5. 运行调度。一个线程Hang了就是这个进程Hang了,一个线程Crash了就是这个进程Crash了,所以多线程要格外小心了,多进程分摊风险更安全。
    6. 软件开发管理。多进程可以分别交给不同团队开发,多线程分别交给不同团队开发很困难,编译要同步,Debug要同步,进程Crash了是哪个团队的责任往往要花半天时间。等等。

    Oracle的这种思维主要是由资源使用决定的,单进程无法满足内存,句柄的使用需求时,只能采用多进程。而Windows微内核结构动态创建进程做得不够好,线程是更好选择,Linux宏内核结构并且线程本来就是通过进程组的方式实现的。

    结论是首先由项目规模决定,这是刚需,再者由运行的系统平台决定,非刚需。

    2、区别

    2.1 通俗理解


     进程是应用程序的执行实例。比如说,当你双击的Microsoft Word的图标,你就开始运行的Word的进程。线程是执行进程中的路径。另外,一个过程可以包含多个线程。启动Word时,操作系统创建一个进程并开始执行该进程的主线程。
     由于一个进程可以由多个线程,线程可以被认为是“轻量级”的过程。因此,一个线程和一个进程之间的本质区别在于,每一个用来完成的工作。线程用于小任务,而进程用于更多的'重量级'的任务 - 应用基本执行。

     一个线程和进程之间的另一个区别是,在同一进程中的线程共享相同的地址空间,而不同的进程没有。因此线程可以读写同样的数据结构和变量,便于线程之间的通信。相反,进程间通信(IPC)很困难且消耗更多资源。

    2.2 CPU时间片层面的理解


    首先来一句概括的总论:

    进程和线程都是一个时间段的描述,是CPU工作时间段的描述。

    下面细说背景:

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

    一个最最基础的事实:

    CPU太快,太快,太快了,寄存器仅仅能够追的上他的脚步,RAM和别的挂在各总线上的设备完全是望其项背。那当多个任务要执行的时候怎么办呢?轮流着来?或者谁优先级高谁来?不管怎么样的策略,一句话就是在CPU看来就是轮流着来。

    一个必须知道的事实:

    执行一段程序代码,实现一个功能的过程介绍 ,当得到CPU的时候,相关的资源必须也已经就位,就是显卡啊,GPS啊什么的必须就位,然后CPU开始执行。
    这里除了CPU以外所有的就构成了这个程序的执行环境,也就是我们所定义的 程序上下文 。当这个程序执行完了,或者分配给他的CPU执行时间用完了,那它就要被切换出去,等待下一次CPU的临幸。在被切换出去的最后一步工作就是保存程序上下文,因为这个是下次他被CPU临幸的运行环境,必须保存。

    串联起来的事实:

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

    ========= 重要的东西出现了========


    进程和线程就是这样的背景出来的,两个名词不过是对应的CPU时间段的描述,名词就是这样的功能。

    进程就是包换上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文

    线程是什么呢?

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

     程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。
     这里a,b,c的执行是共享了A的上下文,CPU在执行的时候没有进行上下文切换的。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的CPU时间段。

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

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

    2.3 CPU资源分配层面的理解

     进程是cpu资源分配的最小单位,线程是cpu调度的最小单位。以前进程既是资源分配也是调度的最小单位,后来为了更合理的使用cpu(实际上是cpu性能越来越好),才将资源分配和调度分开,就有了线程。线程是建立在进程的基础上的一次程序运行单位。

    1. 单进程单线程:一个人在一个桌子上吃菜。
    2. 单进程多线程:多个人在同一个桌子上一起吃菜。
    3. 多进程单线程:多个人每个人在自己的桌子上吃菜。

    3.总结归纳

    以上内容多采自于,从各位大拿处汲取知识,以供学习进步。
    https://www.zhihu.com/question/24351439

  • 相关阅读:
    PAT (Advanced Level) Practice 1054 The Dominant Color (20 分)
    PAT (Advanced Level) Practice 1005 Spell It Right (20 分) (switch)
    PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) (排序)
    hdu 5114 Collision
    hdu4365 Palindrome graph
    单链表查找最大值、两个递增的链表合并并且去重
    蓝桥杯-最短路 (SPFA算法学习)
    蓝桥杯-最大最小公倍数
    Codeforces-470 div2 C题
    蓝桥杯-地宫取宝
  • 原文地址:https://www.cnblogs.com/zhaoxiaolei/p/5405982.html
Copyright © 2011-2022 走看看