day35

一丶GIL锁

什么是GIL锁:

   存在Cpython解释器,全名:全局解释器锁.(解释器级别的锁)

​   GIL是一把互斥锁,将并发运行变成串行.

​   在同一个进程下开启的多个线程,同时只能有一个线程执行,无法利用多核优势

GIL锁的作用:

​   保证同一时间内,共享数据只能被一个任务修改.保证数据的完整性和安全性

​   自动上锁和解锁,不需要人为的添加.减轻开发人员的负担

所谓诟病:单进程的多线程不能利用多核

   通常有人会认为GIL锁不能利用多核处理任务,是Python语言的诟病.个人认为任何一门语言都不是完美的,python问世于20世纪末,当时的CPU也只是单核.

   So,不能利用多核的原因是:同一个进程下,只允许一个线程对共享内容进行修改.不允许多线程同时处理共享数据.

   (打个比方:现在你家有10升(共享数据:10)牛掰的牛奶,你免费送给大家每人1升. 现在有100个人(100个线程)知道了这件事,都上你家来取奶.肯定谁先来,先得. 现在来了10个人(10个线程),每个人都说我去了1升,还剩9升.你真的还剩9升吗? 毛线~~ ,你球都不剩了. 后面来的90个人还能拿到奶吗? 肯定拿拿不到了. So你是不是得上锁,比如你家大门就是一把锁.每次只允许进来(上锁)1个人去奶.取完之后把总的奶量 减一. 第一个取完了出了大门(解锁).剩余的99个人开始抢着进你家门,公平竞争,谁先到你家门,先进就把门锁上了此时发现奶的数量还剩9升,第二个人也只取1升....往后依次延续,当第十一个人进来时,肯定奶已经没了.就表示数据为0.不能再取奶.保证奶的数量的安全性,和完整性(这还是装奶的容器))

GIL抽象图:

   黑色方框就代表GIL锁

二丶验证Cpython的并发效率

需求:

   现在有4个任务(计算密集型任务 或者 IO密集型任务)需要处理.

方案:

   一.开启四个进程

​   二.开启一个进程,四个线程

结果:

   单核:

​      IO密集型:开启进程开销大,进程切换速度远不如线程. 采用一个进程四个线程方案

      计算密集型:没有多核来并行计算,徒增创建进程时间,采用一个进程四个线程方案

   多核:

      IO密集型:尽管多核,开启进程也比较耗时,而且还是要不断的切换.不如线程快.采用一进四线方案

      计算密集型:多核,开启进程并行计算.此时如果用四个线程来会切换回损耗时间.采用四进程方案

多核处理计算密集型:

   多进程的并行执行 单进程的多线程 效率高

# -*-coding:utf-8-*-
# Author:Ds ### 计算密集型
#开启四个进程 , 开启四个线程 from multiprocessing import Process
from threading import Thread
import time
import os def task1():
res=1
for i in range(1,100000000):
res+=i def task2():
res=1
for i in range(1,100000000):
res+=i def task3():
res=1
for i in range(1,100000000):
res+=i def task4():
res=1
for i in range(1,100000000):
res+=i if __name__ == '__main__': start_time=time.time()
### 多核四进程: 处理计算密集型任务,效率高
# 开启四个进程
# p1=Process(target=task1,) # 6.557461261749268
# p2=Process(target=task2,)
# p3=Process(target=task3,)
# p4=Process(target=task4,) ### 虽然本人计算机是多核,但是由于GIL所的原因,同一时刻只允许一个线程处理任务
### 一进程四线程: 处理计算密集型任务,效率低
#开启四个线程
p1=Thread(target=task1,) # 22.048070430755615
p2=Thread(target=task2,)
p3=Thread(target=task3,)
p4=Thread(target=task4,) p1.start()
p2.start()
p3.start()
p4.start() p1.join()
p2.join()
p3.join()
p4.join() print(f'主:{time.time()-start_time}') #### 总结:
#计算密集型: 多进程的并行执行 ~比~ 单进程的多线程 效率高

多核处理IO密集型:

   任务是IO密集型并且任务数量很大,用单进程下的多线程效率高.

from multiprocessing import Process
from threading import Thread
import time
import os def task1():
res=1
time.sleep(3) if __name__ == '__main__': start_time=time.time()
### 并行处理 四核 开启一个进程,使用一个CPU
# 开启进程需要耗费大量时间
# l_t=[]
# for i in range(150):
# ### 多进程处理IO密集型
# p=Process(target=task1) # 耗时: 9.513447999954224
# l_t.append(p)
# p.start()
#
# for j in l_t:
# j.join() ### 并发处理
#虽然是并发处理 ,但是会在CPU之间来回切换.提高效率
l_t = []
for i in range(150):
### 多线程处理IO密集型
p = Thread(target=task1) # 耗时: 3.0212857723236084
l_t.append(p)
p.start() for j in l_t:
j.join() print(f'主:{time.time()-start_time}') #### 总结:
#IO密集型: 任务是IO密集型并且任务数量很大,用单进程下的多线程效率高.

三丶GIL与互斥锁的关系

GIL vs ThreadLock:

​   GIL保护的是解释器级的数据,自动上锁,自动解锁.

   Lock是保护用户自己的数据,手动上锁,手动解锁.如下图:

Python进阶----GIL锁,验证Cpython效率(单核,多核(计算密集型,IO密集型)),线程池,进程池的更多相关文章

  1. Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池

    Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...

  2. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

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

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

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

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

  5. Python并发编程之线程池/进程池--concurrent.futures模块

    一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/ ...

  6. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...

  7. 并发编程~~~多线程~~~计算密集型 / IO密集型的效率, 多线程实现socket通信

    一 验证计算密集型 / IO密集型的效率 IO密集型: IO密集型: 单个进程的多线程的并发效率高. 计算密集型: 计算密集型: 多进程的并发并行效率高. 二 多线程实现socket通信 服务器端: ...

  8. Python并发编程之线程池&进程池

    引用 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/销毁进程或者线程是非常消耗资源的,这个时候我 ...

  9. Python进阶:GIL(全局解释器锁)

    一个不解之谜 一段代码 def CountDown(n): while n > 0: n -= 1 # CountDown(100000000) #==8秒 from threading imp ...

随机推荐

  1. poi导出word表格跨行

    DataCommon.java package com.ksource.pwlp.model.statistic; public class DataCommon { private Long id; ...

  2. odoo开发笔记 -- related用法

    related:字面意思-关联字段,表示本字段引用关联表中的某字段. 格式为:fields.related(关系字段,引用字段,type,relation,string,...),关系字段是本对象的某 ...

  3. kafka window环境下使用(内置zookeeper)

    下载 kafka 官网下载最新版本(已集成 zookeeper) 解压到 D 盘的 kafka_2.12-2.3.0 运行 zookeeper 执行 zookeeper 运行命令 D:\kafka_2 ...

  4. 荔枝派zero从焊接到跑起linux

    步骤 焊flash芯片(如果大于16M,需要改烧录工具的源码) 焊引脚,为了串口看数据 焊接flash芯片,需要注意1号脚的位置,flash芯片在开发板背面,1号脚位置是靠近麦克风的那边 以下为编译相 ...

  5. 设置驱动的方法(Chrome 亲测ok)

    驱动下载地址 http://selenium-release.storage.googleapis.com/index.html package com.selenium.java.webdriver ...

  6. pan wutong团队隐私协议

    本隐私权政策详细说明了pan wutong团队(“我们”或“我们的”)通过我们的应用程序和网站收集的信息,以及我们将如何使用这些信息. 1.我们不会通过我们的应用程序或网站收集儿童的个人信息. 我们深 ...

  7. Entity Framework Core for Console

    包 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCor ...

  8. 【NPDP笔记】第五章 工具与度量

      5.1 创意工具 Ideation 创意开发 创意工具 Scamper Substitute Combine Adapter Modify Put to another use Eliminate ...

  9. Oracle 实现表中id字段自增长

    Oracle 实现表中id字段自增长 最近正在学习Oracle的时候发现Oracle表中的字段不能像mysql中那样可以用auto increment修饰字段从而让id这种主键字段实现自增长. 那Or ...

  10. .NET Core开源Quartz.Net作业调度框架实战演练

    一.需求背景 人生苦短,我用.NET Core!作为一枚后端.NET开发人员,项目实践常遇到定时Job任务的工作,在Windows平台最容易想到的的思路Windows Service服务应用程序,而在 ...