一、全局解释器锁 (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. Spring MVC 起步

    跟踪Spring MVC的请求 在请求离开浏览器时①,会带有用户所请求内容的信息,至少会包含请求的URL. 请求旅程的第一站是Spring的DispatcherServlet.与大多数基于Java的W ...

  2. B2C商城关键技术点总结(站内搜索、定时任务)

    1.站内搜索 1.1Lucene.Net建立信息索引 string indexPath = @"E:\xxx\xxx";//索引保存路径 FSDirectory directory ...

  3. ASP.NET MVC 网站优化之压缩技术

    压缩 html 可以去除代码中无用的空格等,这样可提高网站的加载速度并节省带宽. 实现 ActionFilter 来完成 html 的压缩 public class WhitespaceFilterA ...

  4. Div里超出部分,省略号显示

    1.一行显示并出现省略号 1)三个属性: overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow: hidde ...

  5. 4、JDBC-API

    访问数据库 /** * 在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式: * * Statement * * PrepatedStatement * * CallableS ...

  6. 10、JPA-二级缓存

    pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  7. Linux记录-分区(df/fdisk/mount/umount/fuser)

    1.查看磁盘挂载(df -TH) 2.卸载umount /dev/vdb1 3.查杀用户进程(fuser -m -v -i -k /dev/vdb1) 4.再次卸载umount /dev/vdb1,并 ...

  8. 所有HTTP请求参数及报文查看SERVLET【原】

    HttpRequestServlet.java 说明: 用于接受所有http形式的请求,并把接受到的request中param及getInputStream全打印出来. package king.se ...

  9. openvpn路由配置

    openvpn路由配置 通常openvpn部署好以后,客户端连接VPN后会被配置一些路由,其客户端的路由会被修改为所有的流量都通过VPN来传输.但有时候,我们需要客户端的某些IP走VPN或者本地网关. ...

  10. 让富文本编辑器支持复制doc中多张图片直接粘贴上传

    Chrome+IE默认支持粘贴剪切板中的图片,但是我要发布的文章存在word里面,图片多达数十张,我总不能一张一张复制吧? 我希望打开文档doc直接复制粘贴到富文本编辑器,直接发布 感觉这个似乎很困难 ...