1.GIL概念

1. 什么是GIL(为Cpython解释器)
GIL本身就是一把互斥锁. 原理都一样. 都是让并发的线程同一时间只能执行一个
所以有了GIL的存在. 同一进程下的多个线程同一时刻只能有一个能运行. 无法实现并行 -> 意味着无法利用多核优势 -> 多个CPU同时计算
GIL是影响python运行效率慢的原因之一. 但是不影响并发的执行. 只是无法同时利用多个cpu执行计算 GIL可以被比喻成执行权限. 同一进程下的所有线程要想运行代码都要先抢执行权限 2. 为何要有GIL:
因为Cpython中自带的垃圾回收机制不是线程安全的 -> 需要将GIL锁加在Cpython之上. 控制只能有一个线程在执行.
抢到GIL才能去执行 3. 如果使用:
GIL vs 自定义的互斥锁
GIL相当于执行任务. 会在任务无法执行时. 被强迫释放
自定义互斥锁. 即便是无法执行. 也不回自动释放 4. 多线程执行IO密集型任务会大幅提升效率: 多线程发送网络请求
执行CPU密集型任务反而会降低效率. 因为频繁切换切换线程导致无意义的时间消耗.产生CPU颠簸. CPU负责计算.程序出现io什么都做不了 CPU密集型任务可以使用多进程并发 5. 多线程的并发运行:
每个线程都要先执行请求GIL. 当线程阻塞时(例如IO阻塞). 线程释放GIL. 这时另外一个线程开始运行
操作系统将时间分成多个时间片去运行线程. 线程之间切换速度极快. 肉眼看起来就行是同时运行. 其实并不是同时运行
所以多线程只是并发. 看起来同时运行. 并非并行

2.线程queue

# -*- encoding:utf-8 -*-
# @time: 2022/8/7 16:10
# @author: Maxs_hu
import queue # 队列: 先进先出
q = queue.Queue(5)
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get()) # 堆栈: 先进后出
q = queue.LifoQueue(5) # last in first out
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get()) # 优先级队列: 数字越小. 优先级越高
q = queue.PriorityQueue()
q.put((-1, 'data1'))
q.put((11, 'data2'))
q.put((200, 'data3'))
print(q.get())
print(q.get())
print(q.get()) # (-1, 'data1')
# (11, 'data2')
# (200, 'data3')

3.线程池

"""
1. 什么时候用池:
池的功能是限制启动的进程数量或线程数
什么时候应该限制???
当并发任务数远远超过了计算机承受能力时. 即无法一次性开启过多的进程数或线程数
就应该用池的概念将开启的进程数或者线程数限制在计算机可承受的范围内 2. 同步vs异步
同步和异步是提交任务的两种方式
同步: 类似于串行. 任务提交后等待返回值返回. 再提交下一个任务(和异步对比...基本不用)
异步: 提交完任务后不会在原地等待. 直接运行下一行代码. 等到任务有返回值后会自动触发回调函数
""" from concurrent.futures import ThreadPoolExecutor # 线程池启动器 concurrent 能够同时发生的
import time # =====程序无返回值时=====
def func(name):
for i in range(10):
print(name, i) if __name__ == '__main__':
with ThreadPoolExecutor(9) as t:
# 直接将三百个submit提交给线程池
for i in range(100):
t.submit(func, "周杰伦") # submit 提交
t.submit(func, "薛之谦")
t.submit(func, "林俊杰") # =====程序有返回值时,且需要输出返回值时===== def func(name, t):
time.sleep(t)
print(f"我叫{name}")
return name def parse(res):
print(res.result()) # 注意要加括号 if __name__ == '__main__':
with ThreadPoolExecutor(3) as t:
t.submit(func, "薛之谦", 3).add_done_callback(parse) # callback返回即执行,但执行顺序是不确定的
t.submit(func, "许嵩", 2).add_done_callback(parse) # 这里自动执行,参数也是自动传递
t.submit(func, "林俊杰", 1).add_done_callback(parse) # =====执行顺序确定的线程池===== def func(name, t):
time.sleep(t)
print(f"my name is {name}")
return name if __name__ == '__main__':
with ThreadPoolExecutor(3) as t:
result = t.map(func, ["薛之谦", "林俊杰", "许嵩"], [2, 1, 3]) # map 映射
for res in result:
print(res) # 返回值有特点,是因为多线程较快
# map的返回值是迭代器
# 打印的结果是有序的,且按照分配任务的顺序进行打印

4.进程池

# -*- encoding:utf-8 -*-
# @time: 2022/8/7 21:27
# @author: Maxs_hu # 调用进程池(无返回值):
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import os
import time def task(i):
print('%s is running %s' % (os.getpid(), i))
time.sleep(2) if __name__ == '__main__':
with ProcessPoolExecutor(4) as p: # 创建进程池最多并发四个进程
for i in range(10): # 将9个任务交给进程池执行
p.submit(task, i) # 任务提交 # 进程池(有返回值) -> 返回值无序. 如果想要返回值有序. 则需要使用map函数提交任务
def task(i):
print('%s is running %s' % (os.getpid(), i))
time.sleep(2)
return i ** 2 def parse(res):
print(res.result()) if __name__ == '__main__':
with ProcessPoolExecutor(4) as p:
for i in range(10):
p.submit(task, i).add_done_callback(parse) # 任务提交之后出现返回值就会执行回调函数执行parse. 打印返回值
p.submit(task, i).add_done_callback(parse)

GIL和池的概念的更多相关文章

  1. python之路day06--python2/3小区别,小数据池的概念,编码的进阶str转为bytes类型,编码和解码

    python2#print() print'abc'#range() xrange()生成器#raw_input() python3# print('abc')# range()# input() = ...

  2. IT题库9-线程池的概念和原理

    在什么情况下使用线程池? 1.单个任务处理的时间比较短:2.需要处理的任务的数量大: 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销.2.如不使用线程池,有可能造成系统创建 ...

  3. OC学习篇之---数组对象的引用计数问题和自动释放池的概念

    之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/de ...

  4. OSI传输层TCP与UDP协议、应用层简介、socket模块介绍及代码优化、半连接池的概念

    目录 传输层之TCP与UDP协议 应用层 socket模块 socket基本使用 代码优化 半连接池的概念 传输层之TCP与UDP协议 TCP与UDP都是用来规定通信方式的 通信的时候可以随心所欲的聊 ...

  5. 11月16日内容总结——OSI传输层之TCP与UDP协议、应用层简介、socket模块介绍及代码优化、半连接池的概念

    目录 一.传输层之TCP与UDP协议 1.TCP协议(重要) 三次握手建链接(白话版) 三次握手专业版 四次挥手断连接(白话版) 四次挥手专业版 2.UDP协议 3.tcp和udp的对比 二.应用层简 ...

  6. Python学习之GIL&进程池/线程池

    8.6 GIL锁** Global interpreter Lock 全局解释器锁 实际就是一把解释器级的互斥锁 In CPython, the global interpreter lock, or ...

  7. id,is的用法,小数据池的概念及编码知识进阶

    一:id 查询内存地址 name = 'alex' print(id(name)) li = [1,2,3] print(id(li)) 二:is  判断的是内存地址 name1 = 'alex@' ...

  8. 第三十八天 GIL 进程池与线程池

    今日内容: 1.GIL 全局解释器锁 2.Cpython解释器并发效率验证 3.线程互斥锁和GIL对比 4.进程池与线程池 一.全局解释器锁 1.GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在 ...

  9. GIL 线程池 进程池 同步 异步 阻塞 非阻塞

    1.GIL 是一个全局解释器锁,是一种互斥锁 为什么需要GIL锁:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程都要执行代码 多线程之间要竞争解释器,一旦竞争就有可能出现 ...

  10. GIL 线程池 进程池 同步 异步

    1.GIL(理论 重点)2.线程池 进程池3.同步 异步 GIL 是一个全局解释器锁,是一个互斥锁 为了防止竞争解释器资源而产生的 为何需要gil:因为一个python.exe进程中只有一份解释器,如 ...

随机推荐

  1. ssm框架基本原理

    一.前言 SM框架是标准的MVC模式,将整个系统划分为四层:View层,Controller层,Service层,Dao层 SSM(Spring+SpringMVC+MyBatis)框架集由Sprin ...

  2. w10 端口转发

    场景:同局域网,将其他电脑监听映射到本地.(由于各种安全设计的定点通信) 1.添加端口转发netsh interface portproxy add v4tov4 listenport=4000 li ...

  3. 2020.6.6OO学期末总结

    0.前言 本次博客是对整个java及oo学习情况的一个概略性总结,目的在于反思这半年来的学习情况和实际感受,和具体学习方面的理解和问题. 1.作业过程总结 看着自己一个学期做的所有作业,我想起的是总是 ...

  4. idea设置springboot项目热部署

    转自: https://www.cnblogs.com/zhukf/p/12672180.html 一.什么是热部署? 热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用. 二.什么是Sp ...

  5. python调用java&反编译地址

    反编译工具地址: https://github.com/java-decompiler/jd-gui/releases 你想知道的JPype全在这里∞   先总结自己趟的坑 1. python进程是6 ...

  6. C# winform DataGridView 一列显示星号

    private void myDataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventA ...

  7. VScode好用插件

    1.Anaconda Extension Pack 可以自动补全anaconda包中的属性名称 2.Code Spell Checker 单词拼写检查,非常推荐,有时候会拼错单词,这个不仅可以指出错误 ...

  8. SpringSecurity登录验证,多个用户表

    在开始之前我想感叹一句,技术久了不回头看看真的会忘记的,这次公司让我重新开发一个程序,项目架构为单体多模块开发,其中有个需求就是需要不同用户表进行登录,且不同表的用户名.手机号都可以重复. 这样的需求 ...

  9. Postman设置Cookie参数为全局变量-环境变量设置IP参数

    前提:在遇到多接口测试时,容易出现限制登录的情况 可以使用两种情况: 1.在调用其他接口前,先调用登录接口:这个方法在一般情况下可以,但是对于有些环境,比如像小程序登录时token(或cookie)是 ...

  10. 使用 ww.cad 完成dwg文件转shp(包含所有属性)

    单纯使用ArcEngine提供的接口读取dwg数据转shp存在众多属性无法读取的情况(最直观的 南方cass生产的dwg文件有SOUTH这一字段,为目标要素的类型) private void Conv ...