python多线程及协程

目录

进程和线程

串行和并行

多线程编程

Thread类

创建线程参数

具体案例 

继承Thread类

具体案例

线程池

具体案例

扫描二维码关注公众号,回复: 16162361 查看本文章

协程

协程的使用

协程函数写法

调用多个协程函数

main函数的写法

案例

进程和线程

进程:就是一个程序,运行在系统之上,那么便称这个程序为一个运行进程,并分配ID方便系统管理

线程:线程归于进程,一个进程可开启多个线程执行不同工作,线程是进程的实际工作最小单位

注意

  • 操作系统可以运行多个进程,即多任务运行,一个进程可以有多个线程,即多线程运行
  • 一个进程内至少有一个线程,启动一个程序默认都会有一个主线程
  • 进程之间是内存隔离的,即不同进程拥有各自的内存空间,这就类似于不同的公司拥有不同的办公场所
  • 线程之间是内存共享的,线程是属于进程的,一个进程内的多个线程之间共享这个进程所拥有的内存空间。

串行和并行

  • 串行:任务一个接一个的顺序进行
  • 并行:多个任务同时执行(需CPU的多个核)

多线程编程

Thread类

#导入线程模块
import threading
#创建线程
thread_obj=threading.thread([group],target,[name],[args],[kwargs])
#使线程处于就绪状态
thread_obj.start()

创建线程参数

  • group:暂时无用,未来功能的预留参数
  • target:执行的目标任务名
  • args:以元组的方式给执行任务传参
  • kwargs:以字典的方式给执行的任务传参
  • name:线程名

具体案例 

import threading
import time
def sing(msg):
    while True:
        print(msg)
        time.sleep(1)
def dance(email):
    while True:
        print(email)
        time.sleep(1)
if __name__ == '__main__':
    #因为target是第二个参数,所以必须给参数名进行传参
    sing_thread=threading.Thread(target=sing,args=("我在唱歌……",))
    dance_thread=threading.Thread(target=dance,kwargs={"email":"我在跳舞"})
    #启动线程
    sing_thread.start()
    dance_thread.start()

继承Thread类

from threading import Thread

class MyThread(Thread):
    #重写run方法
    def run(self):
        线程内执行的代码
#创建线程
thread=MyThread()
#让线程处于就绪状态
thread.start()

注意:线程被执行之后,被启动的便是重写后的run方法 

具体案例

from threading import Thread
class MyThread(Thread):
    #重写run方法
    def run(self):
        for i in range(100):
            print(f"子线程:{i}")
if __name__ == '__main__':
    thread=MyThread()
    #开始调用线程
    thread.start()
    for i in range(100):
        print(f"主线程:{i}")

线程池

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

from concurrent.futures import ThreadPoolExecutor
#定义任务
def fn(任务参数):
    任务内执行的代码
#创建线程池,这里面的n表示创建n个线程的线程池
with ThreadPoolExecutor(n) as t:
    #提交任务
    t.submit(fn(任务参数))

具体案例

#导入线程池模块
from concurrent.futures import ThreadPoolExecutor
#定义任务
def fn(name):
    for i in range(100):
        print(name,i)
#main
if __name__ == '__main__':
    #创建线程池
    with ThreadPoolExecutor(50) as t:
        for i in range(100):
            #提交任务
            t.submit(fn("lili"))
    print("线程池的东西全部执行完毕!")

协程

前言:当程序出现IO操作时,可以选择性的切换到其他任务上。

理解:

  • 宏观上我们能看到的是多个任务一起执行
  • 微观上是一个任务一个任务的进行切换,切换条件一般是IO操作

注意:上方所讲的一切,都是在单线程的条件下

协程的使用

导入asyncio模块:import asyncio

协程函数写法

async def 函数名():
    函数体

注意:上面的函数为异步协程函数,函数执行后将会得到一个异步协程对象,若想要调用函数,则需要使用asyncio模块

协程对象=协程函数名()

调用单个协程函数:asyncio.run(协程对象)

import asyncio
async def func():
    print("hello")
if __name__ == '__main__':
    g=func()
    asyncio.run(g)

调用多个协程函数

语法:asyncio.run(main())

main函数的写法

#方法1
async def main():
    f1=协程函数1()
    await f1
    f2=协程函数2()
    await f2

#方法2
async def main():
    tasks=[
        #创建协程任务
        asyncio.create_task(fun1()),
        asyncio.create_task(fun2()),
        asyncio.create_task(fun3())
    ]
    await asyncio.wait(tasks)

案例

#导入协程模块
import asyncio
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=fun1()
    await f1
    f2=fun2()
    await f2
    f3=fun3()
    await f3
if __name__ == '__main__':
    #一次性启动多个任务(异步协程方式)
    asyncio.run(main())

注意:当函数内部出现同步操作(time.sleep(n))时,异步就中断了,这时需要使用异步模块的sleep方法,对于阻塞的方法在前面加await参数,使阻塞的函数等待。

猜你喜欢

转载自blog.csdn.net/m0_60027772/article/details/132168654