首页 > 系统相关 >为什么有了gil锁还要互斥锁、 进程,线程和协程 、什么是鸭子类型

为什么有了gil锁还要互斥锁、 进程,线程和协程 、什么是鸭子类型

时间:2023-08-02 21:59:11浏览次数:30  
标签:协程 互斥 线程 鸭子 进程 gil

目录

1 为什么有了gil锁还要互斥锁

gil:全局解释器锁,线程要执行,必须先获得到gil锁,才能执行
互斥锁:为了保证多线程并发操作数据(变量)而设置的锁,保证在加锁和释放锁之间,其他线程不能操作
gil本质也是大的互斥锁

# 出现了数据错乱,出现了多条线程操作变量,出现的并发安全问题
a=0
线程1要计算: a+=1  
	1 线程1 拿到gil  
    2 读取a=0
    3 假设时间片到了,释放gil,释放cpu
  	4 等待下次被调度执行
    10 轮到它了,获取gil锁
    11 继续往下执行:计算a+1
    12 把结果赋值给a ,a=1
	13 释放gil锁
 线程2要计算: a+=1 
    5 线程2获得了gil锁
    6 读取a=0
    7 计算a+1
    8 把结果赋值给a ,a=1
    9 释放gil锁
# 什么临界区?处出现并发安全问题的这段代码称之为临界区,临界区会出现并发安全问题,所以要在临界区加锁
	# 加锁
	6 读取a=0
    7 计算a+1
    8 把结果赋值给a ,a=1
    # 释放锁

互斥锁保证数据安全

a=0
线程1要计算: a+=1  
	1 线程1 拿到gil  
    # 加锁
    2 读取a=0
    3 假设时间片到了,释放gil,释放cpu
  	4 等待下次被调度执行
    
    7 轮到它了,获取gil锁
    8 继续往下执行:计算a+1
    9 把结果赋值给a ,a=1
	10 释放gil锁
 线程2要计算: a+=1 
    5 线程2获得了gil锁
    #获取锁,获取不到
    6 释放gil锁
    11 获得gil锁
    
    #加锁
    12 读取a=0
    13 计算a+1
    14 把结果赋值给a ,a=1
    15 释放锁
    16 释放gil锁

# gil锁并不锁住临界区,临界区需要我们自己用互斥锁加锁

2 进程,线程和协程

概念
# 进程:是资源分配的最小单位,一个应用程序运行起来,至少有一个进程,进程管理器中就可以看到一个个的进程
# 线程:是cpu调度,执行的最小单位,一个进程下至少有一个线程
# 协程:单线程下的并发,程序层面控制的任务切换

代码如何实现
# 开启多进程两种方式
	-1 写一个类,继承Process,重写类的run方法---》实例化得到对象,对象.start 开启了进程
    -2 通过Process类实例化得到一个对象,传入任务 ,调用对象.start 开启了进程
你在哪里用过

# 同理开启线程两种方式
	-1 写一个类,继承Thread,重写类的run方法---》实例化得到对象,对象.start 开启了进程
    -2 通过Thread类实例化得到一个对象,传入任务 ,调用对象.start 开启了进程
你在哪里用过


# 开启协程
	- 早期之前:借助于第三方gevent,基于greelet写的
    - async 和 await 关键字,不借助于第三方,开启协程  asyncio 包
    	-必须写在一个函数前, async def task()---->这个函数执行的结果是协程函数
        -await 只要是io操作的代码,前面必须加 await

在哪用过

-我一般遇到计算密集型的操作,我会开多进程,io密集型的操作,我一般开多线程
-闲来无事,爬别人数据,喜欢开多线程,爬虫io居多
-程序中,异步做一件事情,也可以开多线程
	比如一个视图函数,异步的吧数据写的文件中
    异步的发送钉钉通知
    异步的发送邮件
-但实际上,在项目中,不需要我们开启进程线程,可以借助于第三方的框架比如celery就可以做异步的操作
而celery的worker,就是进程线程架构
-django框架,是支持并发,我们没有开启多进程和多线程,但是符合uwsgi的web服务器在进入djagno框架之前,开启了进程和线程来执行视图函数

3 什么是鸭子类型

-走路像鸭子,说话像鸭子,我们就可以叫它叫鸭子
-解释:鸭子类型是python面向对象中描述接口的一个概念,区分与其他编程语言,
	比如java:实现接口,必须显示的继承一个接口
    而python:实现接口,遵循鸭子类型,不需要显示的继承一个接口(类),只要类中有对应的属性跟方法,我们就称这几个类的对象为同一种类型

标签:协程,互斥,线程,鸭子,进程,gil
From: https://www.cnblogs.com/yuezongke/p/17601846.html

相关文章

  • 3 Linux多线程开发
    3Linux多线程开发3.1线程概述3.1.1线程概述与进程(process)类似,线程(thread)是允许应用程序并发执行多个任务的一种机制。一个进程可以包含多个线程。同一个程序中的所有线程均会独立执行相同程序,且共享同一份全局内存区域,其中包括初始化数据段、未初始化数据段,以及堆内存段。(......
  • 【Jmeter】跨线程获取cookie值
    1、设置配置文件:apache-jmeter-5.5\bin\jmeter.properties#CookieManagerbehaviour-shouldCookiesbestoredasvariables?#DefaultisfalseCookieManager.save.cookies=true2、线程_登录:2.1、http请求右键_添加_后置处理器_正则表达式提取器 正则表达式:satoken=(......
  • 线程池怎么用?--实例讲解
    线程池使用实例先写一个配置类/***线程池配置*/@ConfigurationpublicclassThreadPoolConfig{//定义线程前缀publicstaticfinalStringNAME_PRE="test";/***ExecutorService这个对象就是线程池,可以点进去他的源码看看*@Bean,将ge......
  • GIL锁;python垃圾回收机制;计算密集型用多进程,io密集型用多线程
    GIL锁;python垃圾回收机制;计算密集型用多进程,io密集型用多线程GIL锁及其作用1.GIL(GlobalInterpreterLock)又称全局解释器锁,本质就是一个互斥锁。2.它保证了cpython进程中的每个线程必须获得这把锁才能执行,不获得不能执行3.这样使得在同一进程内任何时刻仅有一个线程在执行。4......
  • 多任务派发线程处理示例supplyAsync
    packagecom.cytc.test;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.LinkedBlockingQueue;importjava.util.concurrent.ThreadPoolExecutor;importjava......
  • Redis的单线程设计之谜:高性能与简洁并存
    Redis作为一款高性能的内存数据库,以其出色的读写性能和多种数据结构支持而闻名。然而,与其他传统数据库不同,Redis采用了独特的单线程设计。在本文中,我们将揭开Redis单线程设计的奥秘,解释其为何能在单线程下实现高性能,并探讨适用场景与优势。1.Redis单线程模型Redis的单线程模型意味......
  • 多线程任务新jdk8写法
    ListuniqueList=groupIds.stream().distinct().collect(Collectors.toList());//分组后的listList<List<String>>groupedIdList=Lists.partition(uniqueList,10);List<CompletableFuture<ResultBody<List<TyGroupVo>>>>futureLis......
  • JS是门单线程语言
    多线程语言的好处是,在同一时间让cpu处理多个事情。充分的利用cpu多核多线程的资源优势。程序也会执行的更快!支持多线程的语言有特别多,比如java、python等等,但是也有单线程语言如jsclassRunnableDemoimplementsRunnable{privateThreadt;privatefinalStr......
  • 多线程之OMP
    记录在学习games101的时候碰到的多线程知识以下所有结果均在Ubuntu22.04.2LTS操作系统下使用g++11.3.0运行所有的问题来自下面这段代码,这是games101的第七次作业的一部分,需要使用多线程加速PathTracing intuse_critical=0;floatpocess=0;floatsca......
  • 进程与线程
    进程进程就是一个程序的执行实例,也就是正在执行的程序,是操作系统资源分配的基本单位。进程的概念主要有两点:1.进程是一个实体。每个进程都有独立的代码和数据空间(程序上下文),即自己的地址空间。2.进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程......