美文网首页
面试题day0??

面试题day0??

作者: 晨颜 | 来源:发表于2023-08-06 08:49 被阅读0次

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

-并发和并行
-不能控制什么时候释放gil锁
-gil锁不能锁住共享资源


# 1 GIL 本身就是大的互斥锁
# 2 同一个进程下,资源是共享的----》多条线程可以操作同一个变量
# 3 多个线程操作同一个变量,就会出现数据安全问题
# 4 临界区:指一段代码或一段程序片段,需要在同一时间只能被一个线程执行---》多个线程操作临界区,会出现并发安全问题
# 错误的理解
    -有了gil锁,同一时刻,只有一个线程执行,临界区代码,不也只有一个线程在执行吗?只有一个线程在执行,临界区就是安全的,不会出现数据错乱,所以没有必要再加互斥锁了
# 正确的解释:
    gil锁释放不是我们控制的,比如在执行临界区中间,释放了,就会数据错乱问题
# 什么时候会释放gil锁?
    -1 线程遇到io
    -2 时间片轮转,时间片到了,就会自动切换
# 小案例解释
进程中有个变量a=0

临界区:a+=1

线程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锁

# 互斥锁保证数据安全
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
    async def task1():
        a+=1
        time.sleep()
        a+=10

        async def task2():
            a+=2
            await 遇到io
            a+=20    

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


    # 拓展
        不同进程下,资源是隔离的
        进程间通信:IPC 机制
            -消息队列

3 什么是鸭子类型

    # 鸭子类型是python语言面向对象中的一个概念
    #面向对象三大特性
        -继承
        -封装
        -多态
    # 多态和多态性?
        -多态同一类事物的多种形态
        # 现实生活中
            -水:冰,水,水蒸气
            -动物:人,狗,猫,猪
        # 程序中
            -Animal类:子类人,子类狗,子类猫
         -多态性:不考虑对象具体类型的情况下使用对象
         # 程序中
            -len()内置函数---》传参数:字符串对象,列表对象,字典对象
            -len(字典)
         # 为什么能这样用?就是因为多态的存在
            字符串,列表,字典----》属于同一类事物---》有长度的这一类事物


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

相关文章

  • 2017.8.11

    周末了,累 148.8 day0

  • 2017.8.3

    果然不能松懈! 152.3 day0

  • 2017.7.23

    你应该学会克己。 153.9 day0

  • [Day0]1.Two Sum

    After much thought, I title it as "Day0" but not "Day1". ...

  • 2017.8.12

    今天看了冒牌天神,有能力了才能做更多。 149.4 day0

  • day0

    今天学到了什么 工具类的使用 1. 常用的工具类软件 gitTortoiseGitVsCodeSetup用于做项目...

  • day0

    scip 决定要开始学习scip。这是初次学习,对其难度不了解,不敢说很明确的目标,但希望底线是能在50天的时间里...

  • Day0

    下午接到了实习的电话通知,终于要开始去实习了!希望之后的找工作之路也能一直顺利下去?

  • Day0

    After watching 社交网络 Coding While Typing It is Cooooool so...

  • Day0

    测试一下

网友评论

      本文标题:面试题day0??

      本文链接:https://www.haomeiwen.com/subject/faiipdtx.html