• python 并发编程 多线程 GIL全局解释器锁基本概念


    首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。

    就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。

    >有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。

    像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL

    只有CPython 有GIL全局解释器锁

    二 GIL介绍

    GIL本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全。

    可以肯定的一点是:保护不同的数据的安全,就应该加不同的锁。

     

    执行python程序默认会生成一个进程 这个进程就是这个python解释器程序

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import time
    import os
    
    print os.getpid()
    time.sleep(1000)
    [root@salt-server-192 ~]# python create_process.py 
    1343
    #在windows下查看
    tasklist |findstr python
    
    #在linux下下查看
    ps -aux |grep python

    在一个python的进程内,不仅有这个程序的的主线程或者由该主线程开启的其他线程,还有解释器开启的垃圾回收等解释器级别的线程,总之,所有线程都运行在这一个进程内

    1、所有数据都是共享的,这其中,代码作为一种数据也是被所有线程共享的(test.py的所有代码以及Cpython解释器的所有代码)
    例如:test.py定义一个函数work,在进程内所有线程都能访问到work的代码,于是我们可以开启三个线程然后target都指向该代码,能访问到意味着就是可以执行。

    2、所有线程的任务,都需要将任务的代码当做参数传给解释器的代码去执行,即所有的线程要想运行自己的任务,首先需要解决的是能够访问到解释器的代码。

    接上:

    如果多个线程的target=work,那么执行流程是

    多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码去执行

     

    参考python执行程序 三部曲文章 >>

     1.每起一个进程,在内存空间都会默认生成一个主线程

    线程的代码 taget参数 指向python代码 。然后把python代码,当做参数传给解释器的代码去执行,即所有的线程要想运行自己的任务,首先需要解决的是能够访问到解释器的代码。

    图片上的参数就是python代码

     

    2.进程内可以开好多个线程

    CPython里面有一个垃圾回收机制 也是执行解释器代码,所以在进程内,内存空间会有一个垃圾回收线程

    垃圾回收线程运行的是python解释器代码

    因为进程内有4个线程,垃圾回收线程和其他线程会同时执行,垃圾回收线程有可能和其他线程工作冲突,导致数据不安全,

    所以要控制 这些线程一个个运行 需要在CPython解释器里加锁

    解释器的代码是所有线程共享的,所以垃圾回收线程也可能访问到解释器的代码而去执行,这就导致了一个问题:对于同一个数据100,可能线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题没有什么高明的方法,就是加锁处理,如下图的GIL,保证python解释器同一时间只能执行一个任务的代码

    加了互斥锁每个线程要运行,每个线程抢着加锁, 一次执行 只能加锁require() 一次  再加锁require() 一次就变成阻塞状态 要等到释放release() 之后 再加锁require(),

    同一时间只能有一个线程抢到锁,其他线程都要等待

    1.GIL全局解释器锁本质就是互斥锁,加了GIL全局解释器锁 同时运行的多个线程,变成一个一个运行 ,效率低了, 但保证数据安全

    2.只有Cpython解释器才有GIL ,有了互斥锁,对CPython 解释器来说 每启动一个进程 这个进程内的多个线程 同一时间只能有一个在运行

     

    3.也就是说python多线程不能用多核优势,在CPython 想用多核只能用多进程 单核只适合多线程

    4.垃圾回收机制是否一直存在?

    CPython的垃圾回收机制 定时销毁 定时启动的

  • 相关阅读:
    应用Dubbo框架打造仿猫眼项目 理解微服务核心思想
    慕课网--docker走进第一个javaweb应用
    金融行业微服务架构解析-转载炼数成金架构模块金融行业微服务架构解析
    StringEscapeUtils防止xss攻击详解
    尚硅谷 dubbo学习视频
    【面试篇】寒冬求职之你必须要懂的Web安全
    echo "" > 和 echo "" >> 的区别
    python函数、模块、包
    python学习笔记(7)--循环语句
    python学习笔记(6)--条件分支语句
  • 原文地址:https://www.cnblogs.com/mingerlcm/p/9020767.html
Copyright © 2020-2023  润新知