二十九、python多线程、多进程、协程中涉及的知识点

1、GIL全局解释器锁

  https://www.cnblogs.com/nuochengze/p/12664602.html

  1、GIL是CPython解释器的特点, 在其它解释器中不存在

  2、GIL本质是一把互斥锁,但它是解释器级别的锁

  3、它的存在是因为CPython解释器内存管理不是线程安全的

    内存管理,即垃圾回收机制,包括

      引用计数

      标记清除

      分代回收

  4、GIL的存在导致了用一个进程下的多个线程无法利用多核优势

  5、针对不同的数据应该加不同的锁来保证安装

2、互斥锁、死锁与递归锁

  https://www.cnblogs.com/nuochengze/p/12640152.html中1.4同步

3、信号量

  • 信号量在不同的阶段可能对应不同的技术点

  • 在并发编程中信号量指的是

from threading import Semaphore, Thread
import time
import random

sm = Semaphore(5)


def task(name):
    sm.acquire()
    print("%s 正在执行" % name)
    time.sleep(random.randint(1, 5))
    sm.release()


if __name__ == "__main__":
    for i in range(20):
        t = Thread(target=task, args=('%s 号' % i,))
        t.start()

4、Event

# 一些线程/进程等待另外一些线程/进程发送可以运行的信号, 才开始运行

from theading import Event
e = Event()
# 等待
e.wait()
# 发送信号
e.set()

5、队列

  • Queue

    先进先出

  • LifoQueue

    后进先出

  • PriorityQueue

    可以给放入队列中的数据设置优先级

    数字越小,优先级越高

6、池

"""
它的出现是为了保证计算机硬件的安全
降低了程序的运行效率,但是保证了计算机硬件安全
"""

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time

pool = ThreadPoolExecutor(5)  # 池子里面固定只有五个线程
"""
括号内可以传数字,不传的话默认会开设当前计算机CPU个数五倍的线程
池子造出来之后,里面会固定存在五个线程,这5个线程不会重复创建和销毁
"""

"""
将任务提交给池子,就能使用
"""

def task(n):
    print(n)
    return n * n


"""
任务的提交方式:
    同步:提交任务之后原地等待任务的返回结果,期间不做任何事情
    异步:提交任务之后不等待任务的返回结果,继续往下执行
"""


def task_call(n):
    print(">>>> %s" % n.result())

for i in range(20):
    pool.submit(task, i).add_done_callback(task_call)  # submit异步提交
    # submit其实会返回一个Future类的对象,该对象调用result就能获取到任务的结果
    
    # 池子对象的方法
    # pool.shutdown()    # 关闭池子,等待池子中所有的任务运行结束,再继续往后执行代码
    
    # 异步回调机制
    # 给每一个异步提交的任务绑定一个方法,一旦任务有结果了会立即自动触发该方法

7、总结

  多进程下面开设多线程
  多线程下面再开设协程
  从而使程序执行效率提升

posted @ 2020-07-24 16:57  Norni  阅读(132)  评论(0编辑  收藏  举报