一、全局解释器锁 (GIL)
运行test.py的流程:
a、将python解释器的代码从硬盘读入内存
b、将test.py的代码从硬盘读入内存  (一个进程内装有两份代码---一份cpython解释器代码一份test.py代码)
c、将test.py中的代码像  字符串一样  读入python解释器中解析执行
 
1 、GIL:全局解释器锁 (CPython解释器的特性)
#本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL
#同一进程的多个线程必须抢到GIL才能使用CPython解释器解释执行自己的代码,
#同一进程的多线程无法实现并行,但可以实现并发
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(如果没有gil 多线程拿到解释器 并行(现在计算机都是多cup),当x=10的线程中内存中产生一个10,还没来的及绑定x,就有可能被垃圾回收机制回收,为了保证数据安全加gil锁).However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)
GIL本质就是一把加在解释器身上的互斥锁(执行权限)。同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码
 
2、GIL的优缺点:
优点:保证Cpython解释器内存管理的线程安全
缺点:(一个进程内的线程只能一个一个并发执行)在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,也就说Cpython解释器的多线程无法实现并行无法利用多核优势
注意:
a、GIL不能并行,但有可能并发,不一定为串行。(因为串行是一个任务完完全全执行完毕后才进行下一个;而cpython中,一个线程在io时,被CPU释放时,会被强行取消GIL的使用权限)
b、多核(多CPU)的优势是提升运算效率
c、计算密集型--》使用多进程,用上多核,同时存在(cup数的进程)数并行
  多进程:创建新进程(拷贝),切换进程---》开销大(时间上,内存上)
d、IO密集型--》使用多线程 并发
  多线程:创建新线程,切换线程----》开销小(时间上,内存上)
 

二、Cpython解释器并发效率验证
1、计算密集型应该使用多进程
from multiprocessing import Process
from threading import Thread
import time
# import os
# print(os.cpu_count())  #查看cpu个数
def task1():
    res=0
    for i in range(1,100000000):
        res+=i
def task2():
    res=0
    for i in range(1,100000000):
        res+=i
def task3():
    res=0
    for i in range(1,100000000):
        res+=i
def task4():
    res=0
    for i in range(1,100000000):
        res+=i
if __name__ == '__main__':
    # p1=Process(target=task1)
    # p2=Process(target=task2)
    # p3=Process(target=task3)
    # p4=Process(target=task4)
    p1=Thread(target=task1)
    p2=Thread(target=task2)
    p3=Thread(target=task3)
    p4=Thread(target=task4)
    start_time=time.time()
    p1.start()
    p2.start()
    p3.start()
    p4.start()
    p1.join()
    p2.join()
    p3.join()
    p4.join()
    stop_time=time.time()
    print(stop_time - start_time)
2、IO密集型应该使用多线程
from multiprocessing import Process
from threading import Thread
import time
def task1():
    time.sleep(3)
def task2():
    time.sleep(3)
def task3():
    time.sleep(3)
def task4():
    time.sleep(3)
if __name__ == '__main__':
    # p1=Process(target=task1)
    # p2=Process(target=task2)
    # p3=Process(target=task3)
    # p4=Process(target=task4)
    # p1=Thread(target=task1)
    # p2=Thread(target=task2)
    # p3=Thread(target=task3)
    # p4=Thread(target=task4)
    # start_time=time.time()
    # p1.start()
    # p2.start()
    # p3.start()
    # p4.start()
    # p1.join()
    # p2.join()
    # p3.join()
    # p4.join()
    # stop_time=time.time()
    # print(stop_time - start_time) #3.138049364089966
    p_l=[]
    start_time=time.time()
    for i in range(500):
        p=Thread(target=task1)
        p_l.append(p)
        p.start()
    for p in p_l:
        p.join()
print(time.time() - start_time)
三、线程互斥锁与GIL对比
cpython中
GIL能保护解释器级别代码(和垃圾回收机制有关)但保护不了其他共享数据(比如自己的代码)。所以在程序中对于需要保护的数据要自行加锁
gil只是保证一个进程内的所有线程都是并发(不是串行吗)执行,[一个线程在io时,被CPU释放时,会被强行取消GIL的使用权限]
主线程,线程1,线程2,垃圾回收线程》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
  线程1抢到gil 当拿到cpu 解释执行代码:抢到互斥锁 睡 (切—剥夺cpu-强行释放gil锁)改数据  放开互斥锁
  线程2抢到gil 当拿到cpu 解释执行代码:发现互斥锁还没释放等(切-剥夺cpu,强行释放gil)
  线程3。。。
  线程2。。。。
  垃圾线程抢到gil,当拿到cpu 解释执行代码:回收引用计数为0的数据.....
  线程1抢到gil,当拿到cpu 解释执行代码:改数据  放开互斥锁
  。。。。。。。。。。。。。。
from threading import Thread,Lock
import time
mutex=Lock()
count=0
def task():
    global count
    mutex.acquire()
    temp=count
    time.sleep(0.1)
    count=temp+1
    mutex.release()
if __name__ == '__main__':
    t_l=[]
    for i in range(2):
        t=Thread(target=task)
        t_l.append(t)
        t.start()
    for t in t_l:
        t.join()
    print('主',count)

(并发编程)全局解释器锁(GIL)-----有了GIL不用给线程加锁了?的更多相关文章

  1. 并发编程——全局解释器锁GIL

    1.全局解释器锁GIL GIL其实就是一把互斥锁(牺牲了效率但是保证了数据的安全). 线程是执行单位,但是不能直接运行,需要先拿到python解释器解释之后才能被cpu执行 同一时刻同一个进程内多个线 ...

  2. Python并发编程-GIL全局解释器锁

    Python并发编程-GIL全局解释器锁 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.GIL全局解释器锁概述 CPython 在解释器进程级别有一把锁,叫做GIL,即全局解释 ...

  3. GIL全局解释器锁,线程池与进程池 同步异步,阻塞与非阻塞,异步回调

    GIL全局解释器锁 1.什么是GIL 官方解释:'''In CPython, the global interpreter lock, or GIL, is a mutex that prevents ...

  4. Python GIL(全局解释器锁)

    理解并发和并行 并行:多个CPU同时执行多个不同的多任务. 就像两个程序(进程),这两个程序是真的在不同的CPU内同时执行多个任务. 并发:CPU切换处理不同的多任务, 还是有两个程序,但只有一个CP ...

  5. GIL全局解释器锁、死锁现象、python多线程的用处、进程池与线程池理论

    昨日内容回顾 僵尸进程与孤儿进程 # 僵尸进程: 所有的进程在运行结束之后并不会立刻销毁(父进程需要获取该进程的资源) # 孤儿进程: 子进程正常运行 但是产生该子进程的父进程意外死亡 # 守护进程: ...

  6. GIL全局解释器锁、协程运用、IO模型

    GIL全局解释器锁 一.什么是GIL 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C是一套语言(语法)标准,但是可以用不 ...

  7. 15 GIL 全局解释器锁 C语言解决 top ps

    1.GIL 全局解释器锁:保证同一时刻只有一个线程在运行. 什么是全局解释器锁GIL(Global Interpreter Lock) Python代码的执行由Python 虚拟机(也叫解释器主循环, ...

  8. 10 并发编程-(线程)-GIL全局解释器锁&死锁与递归锁

    一.GIL全局解释器锁 1.引子 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Pyt ...

  9. 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁

    一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...

随机推荐

  1. 【codeforces 103E】 Buying Sets

    http://codeforces.com/problemset/problem/103/E (题目链接) 题意 给出$n$个数,每个数与一个集合相关联.从其中选出最小的若干个数,选出的数的个数与这些 ...

  2. 2019.3.18考试&2019.3.19考试&2019.3.21考试

    2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...

  3. 洛谷P2668 斗地主

    好,终于搞完了这一道毒瘤题...... 先想到搜索,然后想到状压,发现数据组数很多,又是随机,还是决定用搜索. 先搜出的多的,于是顺序是三个顺子,然后按照多到少搜带牌,最后是不带牌. 大体思路很简单, ...

  4. C#反射类中所有字段,属性,方法

    可能大家都知道在C#中如何创建一个类,但对于类的结构可能大家不一定了解的很清楚,对于我来说,我之前也搞的不是很明白,今天,当我没事研究反射的时候突然发现了着一点.我们来看类的结构到底是什么 publi ...

  5. pascal与其它语言代码书写的不同和pascal的快捷键

    1.把很多简单语句括起来 begin end; 2.开始,结束 begin end. 3.判断if if (布尔表达式) then begin 语句 end  //没有‘:’ else if () b ...

  6. 关于bottle WEB框架中签名cookie的一点理解

    首先要理解一个概念 MAC (message authenticate code) 消息认证码(带密钥的Hash函数):密码学中,通信实体双方使用的一种验证机制,保证消息数据完整性的一种工具. 构造方 ...

  7. Tomcat定义虚拟主机案例

    Tomcat定义虚拟主机案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.准备环境 1>.创建web程序的根目录 [root@yinzhengjie ~]# mkdir ...

  8. Python字符编码以及循环机制介绍

    Python字符编码以及循环机制介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 身为一名运维人员就得不断的学习,那么如何身为运维的你是否已经嗅探已经很火的Python编程啦?大 ...

  9. java的递归查询大体思路

    场景:递归查询是我们开发中很常见的,如果没有一个比较好的思路,这将会让我们很头疼. 我这里介绍一个查询部门的例子,希望能给你一些启发 部门sql -- ------------------------ ...

  10. Kafka记录-Kafka简介与单机部署测试

    1.Kafka简介 kafka-分布式发布-订阅消息系统,开发语言-Scala,协议-仿AMQP,不支持事务,支持集群,支持负载均衡,支持zk动态扩容 2.Kafka的架构组件 1.话题(Topic) ...