zoukankan      html  css  js  c++  java
  • 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. (However, since the GIL
    exists, other features have grown to depend on the guarantees that it enforces.)
    """
    """
    GIL是一个互斥锁:保证数据的安全(以牺牲效率来换取数据的安全)
    阻止同一个进程内多个线程同时执行(不能并行但是能够实现并发)
    并发:看起来像同时进行的
    GIL全局解释器存在的原因是因为Cpython解释器的内存管理不是线程安全的
    例如:
    线程一正在产生一个变量还没有绑定,这时候垃圾回收线程把它回收掉了,
    对线程一来说就产生了线程数据错误

    垃圾回收机制
    1.引用计数
    2.标记清除
    3.分代回收

    同一个进程下的多个线程不能实现并行但是能够实现并发,多个进程下的线程能够实现并行

    问题:python多线程是不是就没有用了呢?
    四个任务:计算密集的任务 每个任务耗时10s
    单核情况下:
    多线程好一点,消耗的资源少一点
    多核情况下:
    开四个进程:10s多一点
    开四个线程:40s多一点

    四个任务:IO密集的任务 每个任务io 10s
    单核情况下:
    多线程好一点
    多核情况下:
    多线程好一点
    多线程和多进程都有自己的优点,要根据项目需求合理选择

    """

    # 计算密集型
    # from multiprocessing import Process
    # from threading import Thread
    # import os,time
    # def work():
    # res=0
    # for i in range(100000000):
    # res*=i
    #
    #
    # if __name__ == '__main__':
    # l=[]
    # print(os.cpu_count()) # 本机为8核
    # start=time.time()
    # for i in range(8):
    # # p=Process(target=work) #耗时9.252728939056396
    # p=Thread(target=work) #耗时35.369622230529785
    # l.append(p)
    # p.start()
    # for p in l:
    # p.join()
    # stop=time.time()
    # print('run time is %s' %(stop-start))


    # IO密集型
    from multiprocessing import Process
    from threading import Thread
    import threading
    import os,time
    def work():
    time.sleep(2)


    if __name__ == '__main__':
    l=[]
    print(os.cpu_count()) #本机为8核
    start=time.time()
    for i in range(600):
    p=Process(target=work) #耗时4.699530839920044
    # p=Thread(target=work) #耗时2.054128885269165
    l.append(p)
    p.start()
    for p in l:
    p.join()
    stop=time.time()
    print('run time is %s' %(stop-start))
  • 相关阅读:
    ActiveMQ 默认用户名和密码
    # ActiveMQ连接超时问题(java.net.SocketException: Connection reset)
    SpringBoot(十) Logback 配置详解
    postgresql10以上的自动分区分表功能
    基于Redis实现延时队列服务
    Redis(十三):Redis分布式锁的正确实现方式
    Redis(十七):批量操作Pipeline
    Redis(十八):Redis和队列
    PostgreSQL SELECT INTO和INSERT INTO SELECT 两种表复制语句
    PostgreSQL 从文件时间戳获悉一些信息(如数据库创建时间)
  • 原文地址:https://www.cnblogs.com/dongxixi/p/10836218.html
Copyright © 2011-2022 走看看