线程、协程

一、多线程

  • 在url请求时,因为网络各方面原因会阻塞,多线程可以避免阻塞浪费等待时间,但不建议使用多线程
  • 无法无限制的开启多线程,无限制开启会使得CPU频繁创建和销毁线程,浪费CPU的宝贵时间

第一种写法

from threading import Thread


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

if __name__ == '__main__':
	t = Thread(target=func)  # 创建一个线程,并给其安排个任务
	t.start()  # 多线程状态为就绪状态,等待cup的调度
	for i in range(100):
		print("main",i)


第二种写法


from threading import Thread

class MyThread(Thread):
	def run(self):  # 当线程被执行时,被执行的就是run()
		for i in range(100):
			print("子线程",i)
			
			
			
if __name__ == '__main__':
	t = MyThread()
	# t.run()  # 方法的调用 ->是单线程
	t.start()  # 开启线程
	for i in range(100):
			print("主线程",i)

二、多线程传参


from threading import Thread

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

if __name__ == '__main__':
	t = Thread(target=func,args=("me",))
	t.start()
	
	t = Thread(target=func,args=("you",))
	t.start()
	


三、线程池

当阻塞操作远远高于我们线程池中的数量时,效果就不是那么明显

from concurrent.futures import ThreadPoolExecutor

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

if __name__ == '__main__':
        #创建线程池,50个线程
	with ThreadPoolExecutor(50) as t:
                # 创建100个任务
		for i in range(100):
                        # 给线程任务
			t.submit(func,name=f"线程{i}")
			
	print("123")

四、协程

import time


def func():
  print( "我爱黎明")
  time. sleep(3) # 让当前的线程处于阻塞状态。CPU是 不为我工作的
  print ("我真的爱黎明")

if __name__ == '__main__':
  func()

# 指input()程序也是处于阻塞状态
# requests . get(bilibili)在网络请求返回数据之前,程序也是处于阻塞状态的
#一般情况下,当程序处于I0操作的时候。线程都会处于阻塞状态
#协程:当程序遇见了I0操作的时候。 可以选择性的切换到其他任务上。
#在微观上是一个任务一个任务的进行切换,切换条件一般就是I0操作
#在宏观上,我们能看到的其实是多个任务一起在执行
#多任务异步操作
#上方所讲的一切。都是在单线程的条件下


import asyncio

async def func():
  print("你好啊,我叫赛利亚”)

if __name__ == '__main__':

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

五、多任务异步

1、同步

同步就像单线程,方法1执行完,执行方法2,方法2执行完,执行方法3,所花时间是方法1,2,3执行时间的总和

import asyncio
import time

async def func1():
  print ("你好啊,我叫刘德华")
  time.sleep(3)
  print("你好啊,我叫刘德华")

async def func2():
  print("你好啊,我叫王建国")
  time.sleep(2)
  print("你好啊,我叫王建国")

async def func3():
  print("你好啊,我叫李雪琴")
  time.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)

2、异步

方法1执行时阻塞了,切换到别的方法,比如2,
此时方法2执行,在执行过程中,方法2阻塞了,继续切换,比如3
此时方法3执行,在执行过程中,方法3阻塞了,继续切换,比如1

三个方法执行所花时间为,执行时间最长的方法加上切换的时间


import asyncio
import time

async def func1():
  print ("你好啊,我叫刘德华")
  await asyncio.sleep(3)
  print("你好啊,我叫刘德华")

async def func2():
  print("你好啊,我叫王建国")
  await asyncio.sleep(2)
  print("你好啊,我叫王建国")

async def func3():
  print("你好啊,我叫李雪琴")
  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)


3、正确写法

import asyncio
import time

async def func1():
  print ("你好啊,我叫刘德华")
  await asyncio.sleep(3)
  print("你好啊,我叫刘德华")

async def func2():
  print("你好啊,我叫王建国")
  await asyncio.sleep(2)
  print("你好啊,我叫王建国")

async def func3():
  print("你好啊,我叫李雪琴")
  await asyncio.sleep(4)
  print("你好啊,我叫李雪琴")

async def main() :

	tasks = [
		asyncio.create_task(func1()),
		asyncio.create_task(func2()),
		asyncio.create_task(func3())
	]
	
	await asyncio.wait(tasks)




if __name__ == '__main__':
	asyncio.run(main())
  
	t1 = time.time()

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

posted @ 2021-11-06 14:29  lnterpreter  阅读(26)  评论(0编辑  收藏  举报