zoukankan      html  css  js  c++  java
  • python学习第三十节(互斥锁,死锁,迭代锁+信号量)

    python多线程概念的讲解:

    #1、线程与进程的区别是什么?(怎么理解怎么写)
    '''
    进程是程序运行的状态和过程。
    进程会占用内存中的一块空间,消耗资源。
    每个进程最少会有一个线程(主线程),可以有多个线程。
    pyyhon在运行的过程中最多只能有一个线程调用CPU资源,那是因为在每个进程前面有GIL全局解释器锁。
    多个线程通过全局解释器锁是靠操作系统分配的,同一时刻只能有一个线程获得CPU资源 ,如果该线程
    遇到IO操作,操作系统会将CPU分配给别的线程做运算,直到该线程IO操作结束继续计算。
    如果多线程计算过程调用了全局变量就需要注意线程安全的问题,该问题只有多线程运算会遇到,
    线程安全的问题会直接影响程序运行结果。
    线程安全可以用互斥锁、迭代锁来解决。互斥锁相当于用户设置一个锁控制线程调用CPU资源,在一个线程调用CPU的过程中
    即便遇到IO操作由于锁的原因也不会将资源分配给其他线程使用,起到了串行计算的作用,由于互斥锁设置方便,可以自主
    设置锁住的位置和解锁的位置所以比单纯的单线程用JOIN的方式效率更高。
    由于互斥锁功能相对简单,不恰当的使用会导致死锁现象,所以有了迭代锁的概念,用treading.RLock()控制,
    起到线程串行的作用,不会导致线程安全问题。
    '''
    # 2、在 Python 中,哪一种多线程的程序表现得更好,I/O 密集型的还是计算 密集型的?
    '''
    在python中多线程更适用于IO密集型操作,并不适用于计算密集型。
    由于python的机制是当一个线程遇到IO操作的时候会将CPU资源给下一个线程使用,直到IO操作结束才会继续调用CPU资源。
    这样的机制导致PYTHON更适用于IO密集型,而计算密集型在多个线程的时候会处于并发的状态,当一个线程计算一半的时候将
    CPU资源分配给其他的线程计算,上一个计算的结果还需要保存起来,占用资源,另外多个线程计算在切换的过程中是消耗资源的,
    并且计算的效率并没有提升反而有下降,故并不建议用python多线程运行计算密集型的代码。
    '''

    进程是程序运行的状态和过程。

    son类print父类方法,执行失败。因为子类在重写父类方法

     ,但没有num参数。

    线程的另一种使用方法,相当于换一种方式执行函数。
    t1.start()之所以能运行run方法是因为父类里有一个run方法,现在是将其重写了。在python
    thread类里有一个run方法。

     

     函数。模块。类。这三个拥有自己的局部空间。

     

    定义一个空列表
    实例化
    将对象加到列表
    循环start
    GIL(全局解释器锁)
    多个线程无法在同一时刻执行。
    坏处是无法使用多核。

    gil锁为了管理内存而存在,对于用户并没有用。
    gil锁在每个进程前面加一把锁,每个锁只有一个出口让线程出去。
    线程有锁,进程开销太大(每开一个进程就要开辟一段内存空间),只能携程。

    守护进程一般的应用场景是监听,因为守护进程会等主进程结束才结束。主进程结束守护进程也结束。

    线程安全
    在线程去了内存中的变量如果去cpu计算的时候,遇到IO阻塞,其他线程会去取内存中的变量再去CPU计算,继续几次之后,由于IO阻塞结束之后,继续计算,最后计算的结果不一定准确,所以一定要注意IO阻塞。

    r=threading.LOCK() 线程锁

    上图这么写不行,因为循环结束t等于最后一个值,前面的没有了,循环外面写Join只能最后一个是join
    需要在写一个循环将每次都join,如下图

    线程安全问题。
    当线程涉及到全局变量的时候就会出现线程安全问题。
    用互斥锁虽然在多线程的位置是串行,但是在解锁的位置如果在得当的位置,下面无序再串行。
    而如果不用多线程,则所有IO操作都要串行,时间慢很多。


    死锁:就是两个线程在等待对方释放一个锁来运行代码的现象。


    这个互斥锁在加锁的相关位置是相当于串行处理,不加锁的位置没有影响。
    这个互斥锁和join的区别是,互斥锁只在加锁的位置影响,而join影响整个程序。

    死锁,一般的lock.acquire,大锁套小锁之后小锁套大锁,下一个线程会矛盾,之后卡死。

    Rlock.acquire() 递归锁,

    如果Rlock为0 才可以有新的线程进入,进入之后变1 在进入之后+1 为2 ,release之后-1
    遇到信息安全的问题,只能加锁,并且串行计算,这是唯一的方法。

    解决死锁的方法:

     信号量 :限制线程数量的。完成一个进入一个。也是一种锁。

  • 相关阅读:
    生产者消费者模式
    Linux提权(capabilities)
    协程
    xpath常用
    iframe 练习
    python 实现数据库中数据添加、查询与更新
    web网站压力/性能测试经验分享
    AttributeError: module 'applescript' has no attribute 'app'解决方案
    pip3: error: can't exec '/usr/local/bin/pip3' (errno=No such file or directory)报错解决方案
    看了这篇双十一抢购攻略?喜欢的东西还能抢不到?
  • 原文地址:https://www.cnblogs.com/ArmoredTitan/p/7200838.html
Copyright © 2011-2022 走看看