zoukankan      html  css  js  c++  java
  • 【python爬虫】线程&进程

      关注:程序运行速度---->主要是由cpu(大脑)来决定。

         想要提高程序的运行速度----->提高cpu利用率。

      提高cpu的利用率由两种途径:     

        1、让cpu不休息。cpu每时每刻都在处理任务,这个任务可以理解为线程。这种情况就叫做多线程。  

        2、cpu都是分核。每个核就是一个小脑袋。可以理解一心多用。让每个核都作用起来,去干不同的事情,这种方法是就叫多进程

    一、程序、线程、进程

      1、程序:一个应用就可以理解为一个程序。
      2、进程:程序运行资源分配的最小单位,一个程序可以有多个进程。
      3、
    线程:cpu最小的调度单位,必须依赖进程存在。线程是没有独立资源的,所有的线程共享他所在进程的所有资源。

    二、什么是多线程?

      程序中包含多个并行的线程来完成不同的任务。

    三、python中的threading模块

      1、创建多线程的第一种方法

    1 t = threading.Thread(
    2 target = 方法名,
    3 args = (,)  # 参数列表,元组
    4 )
    5 t.start()  # 启动线程

      2、查看线程的数量:threading.enumerate()

    1 enumerate(
    2 可迭代对象,
    3 i,  # 表示索引从i开始。
    4 )  # python的内置函数:枚举可迭代对象,同时获取迭代对象的每个值和其索引。

        可迭代对象:有__iter__属性的对象。
        迭代器:有__iter___和__next__属性的对象。
        这两个如何转化:迭代器=iter(可迭代对象)
        可迭代对象都有:list,tuple,dict,str,bytesarray,set,fp

      3、创建第二种方法: 自定线程类

        (1)python的继承

          ①继承是通过在定义类的时候,类后面的()中添加父类来实现的。
          ②被继承的类称为父类,继承的类称为子类。
          ③子类继承父类所有非私有的属性及方法。
          ④如果子类重写父类的属性和方法,子类默认是优先拿自己的。

        (2)用自定义线程的步骤

          ①继承threading.Thread
          ②重写run方法:
          ③实例化这个类,就相当于创建了一个线程。
            t = MyThread()
            t.start()---默认执行就是run方法里面的内容。
          ④如果自定义线程要传参数,这时候必须要写init方法。必须在init中先调用父类的init(初始化父类。)

        (3)调用父类的init方法有两种方法

          super().__init__()
          threading.Tread.__init__(self)

      4、线程的名称:线程.name查看线程的名称

        如果没有给线程自定义名称,默认线程的名称是:Thread-1,Thread-2,....
        自定义名称:
          t = MyThread(name=str(i))
          t.start()

      5、线程的五种状态

        线程的执行顺序是混乱:线程是cup调度的最小单位,线程的执行完全是由cpu调度所决定的。cpu如何来调度呢?是由线程状态决定。

      6、线程间公用数据的共享问题

        多个线程多全局变量的更改,容易造成数据的混乱。
        解决办法:将线程对公有数据更改部分,用互斥锁锁起来,这两就可以解决这种问题。
        多线程避免多个线程同时处理公有变量。——解耦。

     

    1 import threading
    2 
    3 mutex = threading.Lock()  # 创建一个锁对象
    4 
    5 if mutex.acquire():  # 上锁
    6 
    7 '''
    8     公有数据的处理代码
    9 '''

      mutex.release()#释放锁

        mutex.acquire(True):默认情况就是True,线程到锁这里如果没有获取锁状态,就会被阻塞。
        mutex.acquire(False):线程到锁这里如果没有获取锁状态,不会被阻塞。

    四、多进程和多线程

      1、并发和并行
      2、多线程和多进程的优缺点

        多线程
        (1)多线程的优点
            所有线程可以直接共享内存和变量,线程之间的通信变得容易。
            线程方式消耗的总资源比进程方式少。
        (2)多线程缺点
            程序逻辑和控制方式复杂。
            线程之间的同步和加锁比较麻烦。
            一个线程崩溃可能影响到整个程序的稳定性。

        多进程
        (1)多进程优点
            每个进程都相互独立,不影响主程序的稳定性,子进程崩溃,主程序收到影响比较小。
            通过增加cup,可以轻松扩展性能。
            每个子进程都有2GB地址空间和相关资源,总体性能能够达到的上限非常大。
        (2)多进程的缺点
            逻辑控制复杂,需要和主程序交互。----进程之间通信是很困难度。
            如果有大量数据传送,需要跨进程边界。适合小数量数据传送的程序。

        多进程和多线程如何选择:在实际开发中,选择多线程还是多进程,应该从具体实际开发来进行选择。最好是多进程和多线程结合,即根据实际的需求,每个cpu开启一个子进程,这个子进程开启多个线程进程数据处理。

    五、死锁


      产生死锁的两中情况
        1、同一个线程,先后获取两次锁对象,就会产生死锁。
        2、A获取锁1,B获取锁2,A在不释放锁1的情况试图获取锁2,B在不释放锁2的情况下试图获取锁1,此时就会产生死锁。

     

     

     

  • 相关阅读:
    poj-1001 求高精度幂
    ECS训练营Day1—基于阿里云ECS、VuePress搭建静态网站
    阿里云免费领马克杯答案
    白盒测试之逻辑覆盖 简单易懂~
    如何合并多个PPT?
    failed to connect to gitee.com/github/gitlab port 443: timed out之类的错误
    解决 These dependencies were not found: * core-js/modules/es6.array.fill in xxx 之类的问题
    vue内嵌iframe跨域通信
    Luffy之课程详情页
    Flask之SQLAlchemy,flask_session以及蓝图
  • 原文地址:https://www.cnblogs.com/Tree0108/p/12089559.html
Copyright © 2011-2022 走看看