一、多线程
示例代码1:简单多线程
import time
import threading
def foo(t):
print("foo 开始")
time.sleep(t)
print("foo 结束")
start = time.time()
t_list = []
for i in range(100):
t = threading.Thread(target=foo, args=(2,)) # 注意,如果只有一个参数,必须有逗号,表明是一个元组
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(f"耗时{time.time() - start}秒")
示例代码2:互斥锁
import time
import threading
Lock = threading.Lock()
def addNum():
global num # 在每个线程中都获取这个全局变量
# 上锁
Lock.acquire()
t = num - 1
time.sleep(0.0001)
num = t
Lock.release()
# 放锁
num = 100 # 设定一个共享变量
thread_list = []
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t)
for t in thread_list: # 等待所有线程执行完毕
t.join()
print('Result: ', num)
示例代码3:线程池
import time
from concurrent.futures import ThreadPoolExecutor
def task(i):
print(f'任务{i}开始!')
time.sleep(i)
print(f'任务{i}结束!')
return i
start = time.time()
pool = ThreadPoolExecutor(3)
future_list = []
for i in range(1, 4):
# 线程池技术实现异步,完成并发
future = pool.submit(task, i) # future对象内包含很多内容,如result()为返回值
future_list.append(future)
pool.shutdown() # 阻塞
print(f"耗时{time.time() - start}")
print(future_list)
print([future.result() for future in future_list]) # 打印返回值列表
总结
使用线程池来执行线程任务的步骤如下:
- 调用 ThreadPoolExecutor 类的构造器创建一个线程池。
- 定义一个普通函数作为线程任务。
- 调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务。
- 当不想提交任何任务时,调用 ThreadPoolExecutor 对象的 shutdown() 方法来关闭线程
池。
二、多进程
示例代码:
import multiprocessing
# multiprocessing.Process拥有和threading.Thread()同样的API
import time
def foo(t):
print(f"任务{t} 开始")
time.sleep(t)
print(f"任务{t} 结束")
# 多进程主程序必须写在__main__内
if __name__ == '__main__':
start = time.time()
# 3 基于多进程的并发
t_list = []
for i in range(1, 6):
t = multiprocessing.Process(target=foo, args=(i,))
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(f"耗时{time.time() - start}秒")
三、协程 asyncio
示例代码1:
import asyncio
import time
async def task(i):
print(f"任务{i}启动")
await asyncio.sleep(i)
print(f"任务{i}结束")
start = time.time()
# 创建事件循环对象
loop = asyncio.get_event_loop()
# 构建协程对象列表
tasks = [task(1), task(2), task(3)] # task(1):协程对象coroutine object
print("tasks[0]:", tasks[0])
# 启动运行
loop.run_until_complete(asyncio.wait(tasks)) # 阻塞等待所有的协程结束
print("cost timer:", time.time() - start)
示例代码2: 获取异步任务的结果,回调函数
import asyncio
import time
async def foo(i):
print(f"任务{i}启动")
await asyncio.sleep(i)
print(f"任务{i} {i}秒结束")
return i * i
def task2callback(ret):
print("异步任务2的结果:", ret.result())
start = time.time()
# 创建事件循环对象
loop = asyncio.get_event_loop()
# 构建任务对象列表
tasks = [
asyncio.ensure_future(foo(1)),
asyncio.ensure_future(foo(2)),
asyncio.ensure_future(foo(3)),
] # task(1):asyncio.Task
for task in tasks:
task.add_done_callback(task2callback)
# 启动运行
loop.run_until_complete(asyncio.wait(tasks)) # 阻塞等待所有的协程结束
for task in tasks:
print(task.done(), task.result())
print("cost timer:", time.time() - start)
示例代码3:gather可以返回任务返回值
import asyncio
import time
async def foo(i):
print(f"任务{i}启动")
await asyncio.sleep(i)
print(f"任务{i} {i}秒结束")
return i * i
async def main():
# 构建任务对象列表
tasks = [
asyncio.create_task(foo(1)),
asyncio.create_task(foo(2)),
asyncio.create_task(foo(3)),
]
# 方式1
# tasks[0].add_done_callback(lambda ret: print(ret.result()))
#
# await asyncio.wait(tasks) # 阻塞
#
# for task in tasks:
# print(task.done(), task.result())
# 方式2
rets = await asyncio.gather(*tasks) # gather必须传入多个task对象,不能传入列表
print(rets)
start = time.time()
asyncio.run(main())
print("cost timer:", time.time() - start)
示例代码4: aiohttp
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
async with session.get("http://httpbin.org/headers") as response:
print(await response.text())
asyncio.run(main())
示例代码5:aiohttp 和 aiofiles
import asyncio
import aiohttp
import aiofiles
urls = ["https://img.lianzhixiu.com/uploads/allimg/202109/9999/d1eeaa0450.jpg",
"https://img.lianzhixiu.com/uploads/allimg/202109/9999/6747451f08.jpg",
"https://img.lianzhixiu.com/uploads/allimg/202108/9999/88abd53cc1.jpg"
]
async def aioDownload(url):
# 发送请求
# 得到图片内容
# 保存到文件
print("开始下载")
name = url.rsplit("/", 1)[1] # 从右边切一次,得到[1]位置的内容
async with aiohttp.ClientSession() as session: # 相当于requests
async with session.get(url) as resp: # 相当于resp = requests.get()
# 请求回来了,aiofiles写入文件,
async with aiofiles.open(name, mode='wb') as f: # 创建文件
await f.write(await resp.content.read()) # 读取内容是异步的,需要await挂起,resp.text()
print("下载完成")
async def main():
# 准备异步协程对象列表
tasks = []
for url in urls:
task = asyncio.create_task(aioDownload(url))
tasks.append(task)
await asyncio.wait(tasks)
"""
========================================
主函数功能测试
========================================
"""
if __name__ == '__main__':
# 一次性启动多个任务
# asyncio.run(main())
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
标签:task,python,基础,并发,tasks,time,print,import,asyncio
From: https://www.cnblogs.com/yuan-qi/p/17496794.html