Python多线程&多进程&协程

文章目录

  • 多线程
  • 多进程
  • 线程池
  • 协程

  • 进程是资源单位,每一个进程至少要有一个线程。
  • 线程是执行单位。

多线程

python实现多线程的一个简单例子:

from threading import Thread

def func():
	for i in range(1000):
		print("func", i)

if __name__ == '__main__':
	t = Thread(target=func)		#创建线程并给线程安排任务
	t.start()	#多线程状态为可以开始工作状态,具体执行时间由CPU决定
	for i in range(1000):
		print("mian", i)
from threading import Thread

def func(name):
	for i in range(1000):
		print(name, i)


if __name__ == '__main__':
	t1 = Thread(target=func, args=("周杰伦",))	#传递参数必须是元组
	t1.start()
	
	t2 = Thread(target=func, args=("李荣浩",))
	t2.start()

另一种写法:

class MyThread(Thread):
	def run(self):	#固定的   -> 当线程被执行的时候,被执行的就是run()
		for i in range(1000):
			print("自线程", i)


if __name__ == '__main__':
	t = MyThread()
	# t.run()	#这样变成方法的调用了  -> 变成单线程
	t.start()	#开启线程
	for i in range(1000):
		print("主线程", i)

多进程

python实现多进程的一个简单例子:

from multiprocessing import Process

def func():
	for i in range(1000):
		print("子进程", i)
	
	
if __name__ == '__main__':
	p = Process(target=func)
	p.start()
	for i in range(1000):
		print("主进程", i)

线程池

一次性开辟一些线程,我们用户直接给线程池提交任务,线程任务的调度交给线程池来完成。

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

def fn(name):
	for i in range(1000):
		print(name, i)


if __name__ == '__main__:
	# 创建线程池
	with ThreadPoolExecutor(50) as t:
		for i in range(100):
			t.submit(fn, name=f"线程{i}")
	# 等待线程池中的任务全部执行完毕,才继续执行(守护)
	print('123')

协程

  • time.sleep() 会让当前线程处于阻塞状态, CPU不为它工作
  • input() 程序也是处于阻塞状态
  • requests.get(url) 在网络请求返回数据之前,程序也是处于阻塞状态
  • 一般情况下,当程序处于 IO操作时,线程都会处于阻塞状态

协程:当程序遇见了IO操作的时候,可以选择性的切换到其他任务上。
在微观上是一个任务一个任务的进行切换,切换条件一般就是IO操作;
在宏观上,我们能看到的其实是多个任务在一起进行;
多任务异步操作。
(以上所讲,都是在单线程的条件下)

python编写协程的程序:

import asyncio
import time

#async def func():
#	print("123")

#if __name__ == '__main__':
#	g = func()	# 此时的函数是异步协程函数,此时函数执行得到的是一个协程对象
#	print(g)
#	asyncio.run(g)	# 协程程序运行需要asyncio模块的支持

async def fun1():
	print("我是周杰伦")
	#time.sleep(3)	# 当程序出现了同步操作的时候,异步就中断了  requests.get()同理
	await asyncio.sleep(3)	# 异步操作的代码 await挂起
	print("我是周杰伦")

async def fun2():
	print("我是李荣浩")
	#time.sleep(2)
	await asyncio.sleep(2)
	print("我是李荣浩")
	
async def fun3():
	print("我是大胖橘")
	#time.sleep(4)
	await asyncio.sleep(4)
	print("我是大胖橘")


if __name__ == '__main__':
	f1 = func1()
	f2 = func2()
	f3 = func3()
	tasks = [
		f1, f2, f3
	]
	t1 = time.time()
	asyncio.run(asyncio.wait(tasks))
	t2 = time.time()
	print(t2 - t1)

一般不用上面的写法

async def fun1():
	print("我是周杰伦")
	await asyncio.sleep(3)
	print("我是周杰伦")

async def fun2():
	print("我是李荣浩")
	await asyncio.sleep(2)
	print("我是李荣浩")
	
async def fun3():
	print("我是大胖橘")
	await asyncio.sleep(4)
	print("我是大胖橘")

async def main():
	# 第一种写法:
	# f1 = func1()
	# await f1		# 一般await挂起操作放在协程对象前面
	# 第二张写法(推荐):
	tasks = [
		func1(),	# py3.8以后加上asyncio.create_task(func1())
		func2(),
		func3()
	]
	await asyncio.wait(tasks)

if __name__ == '__main__':
	t1 = time.time()
	# 一次性启动多个任务(协程)
	asyncio.run(main())
	t2 = time.time()
	print(t2 - t1)

你可能感兴趣的:(python,开发语言)