并发编程

Event事件

Event事件
Event事件的作用:
- 用来控制线程的执行.
- 由一些线程去控制另一些线程

from threading import Event

#实例化
e = Event()

#如果出现在线程中,则阻塞(False)
e.wait()

#如果出现在线程中,则则将其他线程中的e.wait()变为True,进入就绪态或运行态 e.set() from threading import Event from threading import Thread import time def light(): print('红灯亮...') time.sleep(5) # 应该开始发送信号,告诉其他线程准备执行 e.set() # 将car中的False ---> True print('绿灯亮...') def car(name): print('正在等红灯....') # 让所有汽车任务进入阻塞态 e.wait() # False print(f'{name}正在加速漂移....') # 让一个light线程任务 控制多个car线程任务 t = Thread(target=light) t.start() for line in range(10): t = Thread(target=car, args=(f'童子军jason{line}号', )) t.start()

线程池和进程池

  1. 什么是进程池与线程池?
    进程池与线程池是用来控制当前程序允许创建(进程/线程)的数量
  2. 进程池与线程池的作用:
    保证在硬件允许的范围内创建 (进程/线程) 的数量
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import time

pool = ThreadPoolExecutor(5)

def task(res): # res == 1 print('线程任务开始了...') time.sleep(1) print('线程任务结束了...') return 123 #回调函数 def call_back(res): print(type(res)) # 注意: 赋值操作不要与接收的res同名 res2 = res.result() #res2 = 123 ,即res2等于task的返回值 print(res2) for line in range(5): pool.submit(task, 1).add_done_callback(call_back) #异步提交 # 会让所有线程池的任务结束后,才往下执行代码 pool.shutdown() print('hello')

利用线程池和回调函数爬虫

协程

  • 进程: 资源单位

    • 线程: 执行单位
    • 协程: 在单线程下实现并发

    注意: 协程不是操作系统资源,他是程序起的名字,为让单线程能实现并发.

    协程的目的:
    - 操作系统:
    多道技术, 切换 + 保存状态
    1) 遇到IO
    2) CPU执行时间过长

    • 协程:
      通过手动模拟操作系统 "多道技术",实现 切换 + 保存状态
      1)手动实现 遇到IO切换, 欺骗操作系统误以为没有IO操作.
      - 单线程 遇到IO, 切换 + 保存状态

            - 单线程 计算密集型, 来回切换 + 保存状态是,反而效率更低

      优点:
      在IO密集型的情况下, 会提高效率.

      缺点:
      若在计算密集型的情况下, 来回切换, 反而效率更低

from gevent import monkey
monkey.patch_all()  # 可以监听该程序下所有的IO操作
import time
from gevent import spawn, joinall # 用于做切换 + 保存状态 def func1(): print('1') # IO操作 time.sleep(1) def func2(): print('2') time.sleep(3) def func3(): print('3') time.sleep(5) start_time = time.time() s1 = spawn(func1) s2 = spawn(func2) s3 = spawn(func3) # s2.join() # 发送信号,相当于等待自己 (在单线程的情况下) # s1.join() # s3.join() # 必须传序列类型 joinall([s1, s2, s3]) end_time = time.time() print(end_time - start_time)

你可能感兴趣的:(并发编程)