• Python GIL 以及线程


    GIL

    GIL: Global Interpreter Lock 全局解释器锁.

    每个 python process 都只创建唯一一个关键资源 GIL,当一个 thread 运行时,它必须获取此 GIL,运行结束再释放。

    由于 GIL 唯一,因此任何时候,一个 process 中都不能有两个 thread 同时运行,一次只能运行一个 thread,这是由 python 的实现决定的,python 不善于以并行方式运行代码。

    python 使用 thread 的意义: 减少等待时间

    虽然 python 不支持两个 thread 并行执行,但是当程序需要等待时,使用线thread 可以缩短等待时间。

    如果所有的 thread 都只是使用CPU,使用 thread 没有意义,因为时间不仅不会缩短,反而会因为 thread 频繁获取和释放 GIL 增加运行时间。

    要创建线程,要先导入 threading 模块:

    from threading import Thread
    
    my_thread = Thread(target=my_func_name)
    my_thread.start()
    
    • 1
    • 2
    • 3
    • 4

    下面的程序有3个 thread: 主线程 main thread 以及 thread 1, thread 2
    ask_user() 函数等待用户输入并输出,complex_calculation() 运行一项需要时间的计算:

    import time
    from threading import Thread
    
    def ask_user():
        start = time.time()
        user_input = input("Enter your name: ")
        greet = f"Hello, {user_input}"
        print(greet)
        print(f'ask_user, {time.time() - start}')
    
    def complex_calculation():
        start = time.time()
        print('Started calculating...')
        [x**2 for x in range(20000000)]
        print(f'complex_calculation, {time.time() - start}')
    
    start = time.time()
    ask_user()
    complex_calculation()
    print(f'Single thread total time: {time.time() - start}')
    
    thread1 = Thread(target=complex_calculation)
    thread2 = Thread(target=ask_user)
    
    start = time.time()
    thread1.start()
    thread2.start()
    
    thread1.join()
    thread2.join()
    
    print(f"Two threads total time: {time.time() - start} ")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    输出如下:

    Enter your name: user
    Hello, user
    ask_user, 2.0858802795410156
    Started calculating...
    complex_calculation, 3.8278822898864746
    Single thread total time: 5.914762496948242
    Started calculating...
    Enter your name: user
    Hello, user
    ask_user, 1.4944937229156494
    complex_calculation, 3.8242249488830566
    Two threads total time: 3.8242249488830566 
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    可见,使用线程,运行时间明显缩短,所用时间对比:

    Single thread total time: 5.914762496948242
    Two threads total time: 3.8242249488830566 
    
    • 1
    • 2

    join() 方法使主线程等待,直到 thread1thread2 运行结束。

  • 相关阅读:
    vue源码分析-从new Vue开始
    Spring依赖注入的简介说明
    使用<a>标签进行文件下载出现文件名称乱码、文件名变下划线
    analog IC layout-Environmental noise
    Hotspot启动原理(一)
    『现学现忘』Docker命令 — 18、镜像常用命令
    Mysql数据库大数据量的解决方案介绍(三、Mycat中间件分片实战)
    关于vscode的GitLens插件里的FILE HISTORY理解
    LeetCode220803_70、在排序数组中查找元素的第一个和最后一个位置
    漏洞复现--Juniper Networks Junos OS EX远程命令执行漏洞(CVE-2023-36845)
  • 原文地址:https://blog.csdn.net/ftell/article/details/125566348