多进程
- python的os模块提供了
fork
函数,但不支持跨平台
- multiprocessing模块的
Process
类创建子进程支持跨平台,并且提供了更高级的封装
- 多进程共享数据可以用管道,套接字等
- multiprocessing提供了一个
Queue
类,基于管道和锁机制提供了多个进程共享的队列
from multiprocessing import Process
from os import getpid
from random import randint
from time import time, sleep
def download_task(filename):
print("启动下载,进程号[%d]"%getpid())
print("开始下载%s..."%filename)
time_to_download = randint(5,10)
sleep(time_to_download)
print("%s下载完成,耗费%d秒"%filename,time_to_download)
def main():
start = time()
p1 = Process(target=download_task, args=("python从入门到放弃.pdf",))
p1.start()
p2 = Process(target=download_task, args=("996 save.pdf",))
p2.start()
p1.join()
p2.join()
end = time()
print("总共耗费%.2f"%(end-start))
if __name__ == "__main__":
main()
多线程
- 早期提供了thread模块(现名为_thread)实现多线程,但很多功能未实现
- 推荐使用threading模块
- 可以继承Thread类来自定义个线程类
-
Lock
Condition
Event
Semaphore
和Barrier
解决多线程互斥的问题
from threading import Thread
from random import randint
from time import time, sleep
def download_task(filename):
print("开始下载%s..."%filename)
time_to_download = randint(5,10)
sleep(time_to_download)
print("%s下载完成,耗费%d秒"%filename,time_to_download)
def main():
start = time()
p1 = Thread(target=download_task, args=("python从入门到放弃.pdf",))
p1.start()
p2 = Thread(target=download_task, args=("996 save.pdf",))
p2.start()
p1.join()
p2.join()
end = time()
print("总共耗费%.2f"%(end-start))
if __name__ == "__main__":
main()
单线程+异步I/O-------python协程
- 基于事件驱动模型
- 没有线程切换的开销
- 不需要多线程的锁机制
- 可以充分利用CPU
- 主要是通过回调或者future对象来获取任务执行结果
-
asyncio
模块和await
和async
关键字来支持异步处理
import asyncio
def num_generator(m, n):
yield from range(m, n+1)
async def prime_filter(m, n):
primes = []
for i in num_generator(m,n):
flag = True
for j in range(2, int(i ** 0.5 + 1)):
if i % j == 0:
flag = False
break
if flag:
primes.append(i)
return tuple(primes)
async def square_mapper(m, n):
squares = []
for i in num_generator(m, n):
squares.append(i * i)
await asyncio.sleep(0.001)
return squares
def main():
loop = asyncio.get_event_loop()
future = asyncio.gather(prime_filter(2,100), square_mapper(1,100))
future.add_done_callback(lambda x: print(x.result))
loop.run_until_complete(future)
loop.close()
if __name__ == "__main__":
main()