threading

  • Lock: 可被其他线程释放

  • .RLock: 与Lock的区别在于可被锁拥有者多次获取,只能被被锁拥有者释放,释放次数等于获取次数才算完全释放

  • Condition:

    • condition实例自带公共锁,调用wait 或者notify之前需要获取公共锁
    • 调用wait时会为当前线程创建一个waiter锁(Lock)并获取,放入dequeue,然后释放公共锁,再次获取waiter锁(因为没有释放, 获取操作会阻塞),最终会重新获取公共锁
    • 调用notify时,会将dequeue中的锁释放
  • Semaphore: 基于Condition, 限制同时acquire的数量,并利用notify来通知waiter

  • Event: 基于Condition,通过一个flag变量来更新状态


queue

  • Queue: 基于一个dequeue 和 一个Lock 和共用Lock 的三个Condition

    • dequeue: 数据get和put
    • not_empty(Condition): 用于get
    • not_ful(Condition): 用于put
    • all_task_done(Condition):用于task_done和join
  • PriortyQueue: 继承Queue,区别在于

    • 使用list存储数据
    • 使用heapq对数据进行排序

multiprocessing

  • Process 通过配置context(或者用默认context)来选择通过什么模式启动子进程, linux下默认用fork模式

  • Lock 通过底层的SemLock实现

  • SimpleQueue: 使用Pipe通信,读和写各用一个锁来保证并发安全

  • Queue put会先放数据到进程的dequeue中缓冲,同时启动一个线程将dequeue中的数据写入到公共Pipe

  • Pool:

    • 启动n个子进程,通过两个SimpleQueue:in_queue接受task、out_queue返回task的结果
    • 主进程启动一个线程接收task_queue的任务,放入in_queue
    • 主进程启动一个线程接收out_queue的结果,放入一个cache dict中
    • apply: 构建一个ApplyResult实例,用一个Event来通知task的状态(_handle_results会更新Event状态)

concurrent.futures

  • Waiter: 统计拥有的futures的状态,根据同步设置(第一次完成、第一次报错、全部完成)等来set Event
  • Future: 存储task的状态结果

参考