• 线程,线程池


    1 学习线程
    
        线程被称作轻量级的进程。  GIL:全局解释锁(只有Cpython解释器才有)
                                  对于线程来说,因为有了GIL,所以没有真正的并行
    
        计算机的执行单位以线程为单位。计算机的最小可执行是线程。
        进程是资源分配的基本单位。线程是可执行的基本单位,是可被调度的基本单位。
        线程不可以自己独立拥有资源。线程的执行,必须依赖于所属进程中的资源。
        进程中必须至少应该有一个线程。
    
        线程又分为用户级线程和内核级线程(了解)
          用户级线程:对于程序员来说的,这样的线程完全被程序员控制执行,调度
          内核级线程:对于计算机内核来说的,这样的线程完全被内核控制调度。
    
    进程由 代码段  数据段  PCB组成(process control block)
    线程由 代码段  数据段  TCB组成(thread control block)
    
    线程和进程的比较
        thread - 线程
        import thread 操作线程的模块
        import threading 用这个去操作线程
       (1) cpu切换进程要比cpu切换线程 慢很多
           在python中,如果IO操作过多的话,使用多线程最好了
       (2) 在同一个进程内,所有线程共享这个进程的pid,也就是说所有线程共享所属进程的所有资源和内存地址
       (3) 在同一个进程内,所有线程共享该进程中的全局变量
    
       (4) 因为有GIL锁的存在,在Cpython中,没有真正的线程并行。但是有真正的多进程并行
           当你的任务是计算密集的情况下,使用多进程好
          总结:在CPython中,IO密集用多线程,计算密集用多进程
    
      (5)关于守护线程和守护进程的事情(注意:代码执行结束并不代表程序结束)
          守护进程:要么自己正常结束,要么根据父进程的代码执行结束而结束
          守护线程:要么自己正常结束,要么根据父线程的执行结束而结束
    


    2线程的使用方法
    (1)锁机制
    递归锁
    RLock() 可以有无止尽的锁,但是会有一把万能钥匙
    互斥锁:
    Lock() 一把钥匙配一把锁
    GIL:全局解释器锁
    锁的是线程,是CPython解释器上的一个锁,锁的是线程,意思是在同一时间只允许一个线程访问cpu

    (2) 信号量:
    from threading import Semaphore
    去看多进程的信号量

    (3) 事件
    from threading import Event
    去看多进程的事件机制

    (4) 条件
    from threading import Condition
    条件是让程序员自行去调度线程的一个机制
    # Condition涉及4个方法
    # acquire()
    # release()
    # wait() 是指让线程阻塞住
    # notify(int) 是指给wait发一个信号,让wait变成不阻塞
    # int是指,你要给多少给wait发信号

    (5) 定时器
    from threading import Timer
    # Timer(time,func)
    # time:睡眠的时间,以秒为单位
    # func:睡眠时间之后,需要执行的任务

    线程队列: queue.Queue() queue.LifoQueue queue.priority(优先级队列)
    # 复习
    from multiprocessing import Queue
    # 用于多进程的队列,专门用来做 IPC Inter-Process Communication,进程间通信

    import queue # 用于同一进程内的队列,不能做多进程间的通信

    q = queue.Queue() # 先进先出
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get()) # 没有不会报错
    print(q.get_nowait()) # 没有会报错


    q = queue.LifoQueue() # 后进先出
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get()) # 没有不会报错
    print(q.get_nowait()) # 没有会报错

    q = queue.PriorityQueue()
    # PriorityQueue 优先队列, put()里面 为一个元祖,第一位是优先级,第二位为数据
    # put((1,'item'))
    # 优先级如果是数字,直接比较数值
    # 如果是字符串,是按照 ASCII 码比较的。当ASCII码相同时,会按照先进先出的原则

    q.put((5,1))
    q.put((2,'aaaa'))
    q.put((9,[1,2,3]))

    print(q.get())
    print(q.get())
    print(q.get())

    线程池 concurrent.features 中的 ThreadPoolExecutor

    方法: map submit shutdown
    from concurrent.futures import ThreadPoolExecutor
    
    def func(num):
        print('This is my %s times' % num)
    
    t = ThreadPoolExecutor(20)
    
    # 线程池方法
    # t.map() # 提交任务 等效于 for循环 + submit
    # t.submit() # 提交任务
    # t.shutdown()
    
    # -----添加任务方法1-------
    # t.map(func,range(1000))
    # t.shutdown()
    
    # -----添加任务方法2-------
    # for i in range(1000):
    #     t.submit(func,i)
    # t.shutdown()
    
    
    
    







  • 相关阅读:
    Linux下的游戏及模拟器
    [Java]学习Java(3)数组、字符串
    [Javascript]Event属性
    下载文件名乱码
    比那 施氏食狮史 还要强的文章
    [Javascript]脚本学习(1)
    [Java]学习Java(2)基本类型与对象
    [Java]学习Java(1)运算符&语句&类
    LumaQQ开发文档
    Extensions for FireFox
  • 原文地址:https://www.cnblogs.com/niuli1987/p/9524304.html
Copyright © 2020-2023  润新知