zoukankan      html  css  js  c++  java
  • GIL全局解释器锁与协程

    一、GIL全局解释器锁

    在同一个进程下开启的多线程,同一时刻只能有一个线程执行,因为Cpython的内存管理不是线程安全

    GIL全局解释器锁,本质上就是一把互斥锁,保证数据安全

     1 import time
     2 from threading import Thread
     3 
     4 n = 100
     5 
     6 
     7 def task():
     8     global n
     9     m = n
    10     time.sleep(3)
    11     n = m - 1
    12 
    13 
    14 if __name__ == '__main__':
    15     list1 = []
    16     for line in range(10):
    17         t = Thread(target=task)
    18         t.start()
    19         list1.append(t)
    20 
    21     for t in list1:
    22         t.join()
    23 
    24     print(n)

    在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势

    优点:

      保证数据的安全性

    缺点:

      单个进程下,开启多个线程,牺牲执行效率,无法实现并行,只能实现并发

    不同情况下使用多进程或者多线程比较

    IO密集型下使用多线程.
    计算密集型下使用多进程

     1 # 计算密集型任务
     2 def task1():
     3     # 计算1000000次 += 1
     4     i = 10
     5     for line in range(10000000):
     6         i += 1
     7 
     8 
     9 # IO密集型任务·
    10 def task2():
    11     time.sleep(3)
    12 
    13 
    14 if __name__ == '__main__':
    15     # 1、测试多进程:
    16     # 测试计算密集型
    17     start_time = time.time()
    18     list1 = []
    19     for line in range(6):
    20         p = Process(target=task1)
    21         p.start()
    22         list1.append(p)
    23     for p in list1:
    24         p.join()
    25     end_time = time.time()
    26     # 消耗时间: 0.9640259742736816
    27     print(f'计算密集型消耗时间: {end_time - start_time}')
    28 
    29     # 测试IO密集型
    30     start_time = time.time()
    31     list1 = []
    32     for line in range(6):
    33         p = Process(target=task2)
    34         p.start()
    35         list1.append(p)
    36     for p in list1:
    37         p.join()
    38     end_time = time.time()
    39     # 消耗时间: 3.1492795944213867
    40     print(f'IO密集型消耗时间: {end_time - start_time}')
    41 
    42 
    43     # 2、测试多线程:
    44     # 测试计算密集型
    45     start_time = time.time()
    46     list1 = []
    47     for line in range(6):
    48         p = Thread(target=task1)
    49         p.start()
    50         list1.append(p)
    51     for p in list1:
    52         p.join()
    53     end_time = time.time()
    54     # 消耗时间: 3.3614895343780518
    55     print(f'计算密集型消耗时间: {end_time - start_time}')
    56 
    57     # 测试IO密集型
    58     start_time = time.time()
    59     list1 = []
    60     for line in range(6):
    61         p = Thread(target=task2)
    62         p.start()
    63         list1.append(p)
    64     for p in list1:
    65         p.join()
    66     end_time = time.time()
    67     # 消耗时间: 3.002037763595581
    68     print(f'IO密集型消耗时间: {end_time - start_time}')

    二、协程

    进程、线程、协程: 

    - 进程: 资源单位
    - 线程: 执行单位
    - 协程: 单线程下实现并发

    在IO密集型的情况下,使用协程能提高最高效率

    协程作用:

      手动实现 “遇到IO切换 + 保存状态” 来欺骗操作系统,让操作系统误以为没有IO操作,将CPU的执行权限给你

     1 from gevent import monkey  # 猴子补丁
     2 monkey.patch_all()  # 监听所有的任务是否有IO操作
     3 from gevent import spawn  # spawn(任务)
     4 from gevent import joinall
     5 import time
     6 
     7 def task1():
     8     print('start from task1...')
     9     time.sleep(1)
    10     print('end from task1...')
    11 
    12 def task2():
    13     print('start from task2...')
    14     time.sleep(3)
    15     print('end from task2...')
    16 
    17 def task3():
    18     print('start from task3...')
    19     time.sleep(5)
    20     print('end from task3...')
    21 
    22 
    23 if __name__ == '__main__':
    24 
    25     start_time = time.time()
    26     sp1 = spawn(task1)
    27     sp2 = spawn(task2)
    28     sp3 = spawn(task3)
    29     # sp1.start()
    30     # sp2.start()
    31     # sp3.start()
    32     # sp1.join()
    33     # sp2.join()
    34     # sp3.join()
    35     joinall([sp1, sp2, sp3])
    36 
    37     end_time = time.time()
    38 
    39     print(f'消耗时间: {end_time - start_time}')
  • 相关阅读:
    Visual Studio Code 上java开发环境搭建
    c++编译时打印宏定义
    git使用
    Let's Encrypt申请证书及使用
    使用docker创建aosp编译环境
    项目中使用protobuf 3.0
    ubuntu14.04 安装mono
    ubuntu14.04 安装apache+mysql+php
    Discuz & UCenter 修改手记
    代码细节重构:请对我的代码指手划脚(四)
  • 原文地址:https://www.cnblogs.com/hexianshen/p/12011369.html
Copyright © 2011-2022 走看看