zoukankan      html  css  js  c++  java
  • 线程、进程、协程和GIL(一)

      参考链接:https://www.cnblogs.com/alex3714/articles/5230609.html

           https://www.cnblogs.com/work115/p/5620272.html

      编程离不开并发,而并发的基础就离不开线程、进程、协程。那么什么是线程、进程、协程呢?

    进程:

      进程是对资源进行分配和调度的最小单位,是操作系统结构的基础,是线程的容器(就像是一幢房子,一个空壳子,并不能运动)。

      线程的概念主要有两点:

        1、进程是一个实体,每个进程都有自己的地址空间,一般包括文本区域(text region)、数据区域(data region)和堆栈(stack region)

        文本区域存储处理器执行的代码;数据区域存储变量和进程在执行期间所使用的动态分配的内存;堆栈区域存储在活动过程中所调用的指令和本地变量

        2、进程是一个“执行中的程序”。程序是一个没有生命的实体,只有在操作系统调用时,他才会成为一个活动的实体:进程。

    线程:

      线程被称为轻量级进程,是操作系统能够运算调度的最小单位,线程被包含在进程中,是进程中实际处理单位(就像是房子里的人,人才能动)

        一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组 成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,

      线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个 进程的其它线程共享进程所拥有的全部资源

      一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程 在运行中呈现出间断性。

      线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;

      运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。

      每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

    进程与线程的区别:

      进程是资源分配的最小单位,线程是系统调度(程序执行)的最小单位。

      进程有自己独占的地址空间,每启动一个进程,系统就需要为它分配地址空间;

      而一个进程下所有线程共享该进程的所有资源,使用相同的地址空间,因此CPU在线程之间切换远远比在进城之间切换花费小,而且创建一个线程的开销也远远比开辟一个进程小得多。

      线程之间通信更加方便,同一进程下所有线程共享全局变量、静态变量等数据。而进程之间通信需要借助第三方。

      线程只能归属于一个进程并且它只能访问该进程所拥有的资源。当操作系统创建一个进程后,该进程会自动申请一个名为主线程或首要线程的线程。

      处理IO密集型任务或函数用线程;

      处理计算密集型任务或函数用进程。

    协程:

      协程又叫微线程,一个程序可以包含多个协程,就好比一个进程包含多个线程。协程的调度完全由用户控制。

      协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,

      直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

      协程和线程的阻塞是有本质区别的。协程的暂停完全由程序控制,线程的阻塞状态是由操作系统内核来进行切换。

      因此,协程的开销远远小于线程的开销。

    线程和协程的区别:

      一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。

      线程进程都是同步机制,而协程则是异步

      协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态

      我们常说python中的多线程都是假的,因为无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行。

      这又是为什么呢?其实这主要是由于GIL的存在而造成的,那么GIL又是什么呢?

    GIL:

       GIL(Global Interpreter Lock) 全局解释器锁

      官方解释:In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once.

      This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.

      什么意思呢?在CPython中,全局解释器锁是一个互斥锁,它可以防止多个本机线程同时执行Python字节码。这个锁是必要的,主要是因为CPython的内存管理不是线程安全的。简而言之,GIL其实就是一个全局排它锁,他规定了在同一时间仅仅只能有一个线程来对数据进行操作。

      首先说一下,这个GIL并不是python的缺陷,它仅仅在CPython中存在,这是因为在最初,python是由C写的,在起线程时是直接调用的操作系统的系统线程。

      所以GIL仅仅在Cpython的python解释器中存在该问题,其他的如JPython就没有这个问题,但是大多数的python执行环境默认使用CPython解释器,

      所以GIL这个问题比较常见。

     

      理清了进程、线程、协程和GIL的基本概念,下一篇博客我们再来说说在Python中如何创建线程、进程、协程。

    想了解更多Python关于爬虫、数据分析的内容,欢迎大家关注我的微信公众号:悟道Python

      

      

      

      

  • 相关阅读:
    HDU5779 Tower Defence
    Python练习题2.14求整数段和
    Python练习题2.13分段计算居民水费
    Python练习题2.12输出三角形面积和周长
    Python练习题2.11求平方与倒数序列的部分和
    Python练习题2.9比较大小
    Python练习题2.8转换函数使用
    Python练习题2.7产生每位数字相同的n位数
    Python练习题2.6求交错序列前N项和
    Python练习题2.5求奇数分之一序列前N项和(存在问题)
  • 原文地址:https://www.cnblogs.com/ss-py/p/10236125.html
Copyright © 2011-2022 走看看