【知识点】进程,线程,协程 介绍
2023年 01月 20 日

BIGFISH

线程,进程,协程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E5Gnb3rp-1630165452378)(D:\tec-note\photos\image-20210824191000831.png)]

一、进程

多进程:

  • 是CPU对程序的一次执行过程、一次执行任务。各个进程有自己的内存空间、数据栈等。操作系统分配内存的基本单位(打开、执行、保存…)

  • 参考:Python基础之进程(Process)zxnode的博客-CSDN博客python process

  • import os
    from multiprocessing import Process
    
    def func_one():
    print("这是第一个子进程")
    print("son_one:%s  father:%s" % (os.getpid(), os.getppid()))
    for i in range(1000):
    print("第一个子进程", i)
    
    def func_two():
    print("这是第二个子进程")
    print("son_two:%s  father:%s" % (os.getpid(), os.getppid()))
    for i in range(1000):
    print("这是第二个子进程", i)
    
    if __name__ == '__main__':
    p_one = Process(target=func_one)
    P_two = Process(target=func_two)
    #多个进程可以同用一个函数
    #    P_two = Process(target=func_two,args=("函数一",))
    p_one.start()
    #p_one.join()  # 主线程要等待func_one终止,才继续往下走
    P_two.start()
    print("son:%s  father:%s" % (os.getpid(), os.getppid()))  # father是pycharm

进程池:

  • import time
    from concurrent.futures import ProcessPoolExecutor
    
    def fun(name):
    for i in range(1000):
    print(name,i)
    
    if __name__ == '__main__':
    #创建进程池
    with ProcessPoolExecutor(50) as t:
    for i in range(100):
    t.submit(fun,name=f"进程{i}")
    #等待进程池中的任务全部执行完毕,才能继续执行
    print("已经全部完成!")

二、线程

多线程:

  • 是进程中执行运算的最小单位,是进程中的一个实体。(打开、执行、保存…)

  • 一个程序至少有一个进程,一个进程至少有一个线程。

  • 操作系统分配CPU的基本单位

  • 参考:Python线程详解劲节子的博客-CSDN博客python 线程

  • from threading import Thread
    
    def fun(name):
    for i in range(1000):
    print(name,1)
    
    if __name__ == '__main__':
    #创建线程并且给线程安排任务
    p_one = Thread(target=fun,args=("第一个子线程",))
    p_two = Thread(target=fun,args=("第二个子线程",))
    #多线程状态为开始工作状态,具体的执行时间由CPU决定
    p_one.start()
    p_two.start()

线程池:

  • from concurrent.futures import ThreadPoolExecutor
    def fun(name):
    for i in range(1000):
    print(name,i)
    
    if __name__ == '__main__':
    #创建线程池
    with ThreadPoolExecutor(50) as t:
    for i in range(100):
    t.submit(fun,name=f"子线程{i}")
    #等待所有线程全部完成,才会执行下面代码(守护)
    print("所有线程已经全部完成!!!")

线程池实战

  • import time
    from concurrent.futures import ThreadPoolExecutor
    
    def download(url,i):
    time.sleep(2)
    print(f"第{i}页下载完成!")
    
    if __name__ == '__main__':
    with ThreadPoolExecutor(100) as t:
    for i in range(1000):
    url = f"www.mbigfish.com?id={i}"
    t.submit(download, url, i)
    
    print("全部下载完成!")

三、协程

协程结束

  • 协程是一种用户态的轻量级线程,协程的调度完全由用户控制。

  • 一个线程可以拥有多个协程,协程不是被操作系统内核所管理,而完全是由程序所控制。

  • 与其让操作系统调度,不如我自己来,这就是协程

  • import asyncio
    import time
    
    
    async def fun1():
    print('第一个函数开始')
    #time.sleep(2) 当程序出现了同步操作的时候,异步就中断了
    await asyncio.sleep(2) #异步操作的代码
    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 fi 一般await挂起操作放在协程对象前面
    # 第二中写法(推荐)
    tasks = [
    asyncio.create_task(fun1()),
    asyncio.create_task(fun2()),
    asyncio.create_task(fun3())
    ]
    
    await asyncio.wait(tasks)
    
    if __name__ == '__main__':
    t1 = time.time()
    asyncio.run(main())
    t2 = time.time()
    print('所需时间:', t2-t1)

协程下载模板

  • import asyncio
    import time
    
    
    async def download(url):
    print(url,'下载开始')
    await asyncio.sleep(2)
    print(url,'下载结束')
    
    async def main():
    urls = [
    'www.a1.com',
    'www.a2.com',
    'www.a3.com',
    'www.a4.com',
    'www.a5.com',
    'www.a6.com',
    ]
    
    tasks = []
    for url in urls:
    d = asyncio.create_task(download(url))
    tasks.append(d)
    
    await asyncio.wait(tasks)
    
    if __name__ == '__main__':
    t1 = time.time()
    asyncio.run(main())
    t2 = time.time()
    print('所需时间:', t2 - t1)

协程下载实战

  • import asyncio
    import aiohttp
    import time
    
    async def download(url):
    name = url.rsplit('/', 1)[1]
    async with aiohttp.ClientSession() as session:
    async with session.get(url) as req:
    # 请求回来了,写入文件
    with open(name,'wb') as fp:
    #读取内容是异步的,需要await挂起
    fp.write(await req.content.read())
    print(name,'下载完成!')
    
    async def main():
    urls = [
    'https://pic.quanjing.com/c6/cx/QJ6880697447.jpg',
    'https://pic.quanjing.com/3g/lv/QJ6594284520.jpg',
    'https://pic.quanjing.com/ng/wd/QJ8166536175.jpg',
    'https://pic.quanjing.com/hj/jj/QJ6802044841.jpg',
    'https://pic.quanjing.com/tn/6t/QJ9127562743.jpg',
    'https://pic.quanjing.com/39/uc/QJ7108531848.jpg',
    ]
    
    tasks = []
    for url in urls:
    d = asyncio.create_task(download(url))
    tasks.append(d)
    
    await asyncio.wait(tasks)
    
    if __name__ == '__main__':
    t1 = time.time()
    #asyncio.run(main()) 会报错
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    
    t2 = time.time()
    print('所需时间:', t2 - t1)

【知识点】进程,线程,协程 介绍

线程,进程,协程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E5Gnb3rp-1630165452378)(D:\tec-note\photos\image-20210824191000831.png)]

一、进程

多进程:

  • 是CPU对程序的一次执行过程、一次执行任务。各个进程有自己的内存空间、数据栈等。操作系统分配内存的基本单位(打开、执行、保存…)

  • 参考:Python基础之进程(Process)zxnode的博客-CSDN博客python process

  • import os
    from multiprocessing import Process
    
    def func_one():
    print("这是第一个子进程")
    print("son_one:%s  father:%s" % (os.getpid(), os.getppid()))
    for i in range(1000):
    print("第一个子进程", i)
    
    def func_two():
    print("这是第二个子进程")
    print("son_two:%s  father:%s" % (os.getpid(), os.getppid()))
    for i in range(1000):
    print("这是第二个子进程", i)
    
    if __name__ == '__main__':
    p_one = Process(target=func_one)
    P_two = Process(target=func_two)
    #多个进程可以同用一个函数
    #    P_two = Process(target=func_two,args=("函数一",))
    p_one.start()
    #p_one.join()  # 主线程要等待func_one终止,才继续往下走
    P_two.start()
    print("son:%s  father:%s" % (os.getpid(), os.getppid()))  # father是pycharm

进程池:

  • import time
    from concurrent.futures import ProcessPoolExecutor
    
    def fun(name):
    for i in range(1000):
    print(name,i)
    
    if __name__ == '__main__':
    #创建进程池
    with ProcessPoolExecutor(50) as t:
    for i in range(100):
    t.submit(fun,name=f"进程{i}")
    #等待进程池中的任务全部执行完毕,才能继续执行
    print("已经全部完成!")

二、线程

多线程:

  • 是进程中执行运算的最小单位,是进程中的一个实体。(打开、执行、保存…)

  • 一个程序至少有一个进程,一个进程至少有一个线程。

  • 操作系统分配CPU的基本单位

  • 参考:Python线程详解劲节子的博客-CSDN博客python 线程

  • from threading import Thread
    
    def fun(name):
    for i in range(1000):
    print(name,1)
    
    if __name__ == '__main__':
    #创建线程并且给线程安排任务
    p_one = Thread(target=fun,args=("第一个子线程",))
    p_two = Thread(target=fun,args=("第二个子线程",))
    #多线程状态为开始工作状态,具体的执行时间由CPU决定
    p_one.start()
    p_two.start()

线程池:

  • from concurrent.futures import ThreadPoolExecutor
    def fun(name):
    for i in range(1000):
    print(name,i)
    
    if __name__ == '__main__':
    #创建线程池
    with ThreadPoolExecutor(50) as t:
    for i in range(100):
    t.submit(fun,name=f"子线程{i}")
    #等待所有线程全部完成,才会执行下面代码(守护)
    print("所有线程已经全部完成!!!")

线程池实战

  • import time
    from concurrent.futures import ThreadPoolExecutor
    
    def download(url,i):
    time.sleep(2)
    print(f"第{i}页下载完成!")
    
    if __name__ == '__main__':
    with ThreadPoolExecutor(100) as t:
    for i in range(1000):
    url = f"www.mbigfish.com?id={i}"
    t.submit(download, url, i)
    
    print("全部下载完成!")

三、协程

协程结束

  • 协程是一种用户态的轻量级线程,协程的调度完全由用户控制。

  • 一个线程可以拥有多个协程,协程不是被操作系统内核所管理,而完全是由程序所控制。

  • 与其让操作系统调度,不如我自己来,这就是协程

  • import asyncio
    import time
    
    
    async def fun1():
    print('第一个函数开始')
    #time.sleep(2) 当程序出现了同步操作的时候,异步就中断了
    await asyncio.sleep(2) #异步操作的代码
    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 fi 一般await挂起操作放在协程对象前面
    # 第二中写法(推荐)
    tasks = [
    asyncio.create_task(fun1()),
    asyncio.create_task(fun2()),
    asyncio.create_task(fun3())
    ]
    
    await asyncio.wait(tasks)
    
    if __name__ == '__main__':
    t1 = time.time()
    asyncio.run(main())
    t2 = time.time()
    print('所需时间:', t2-t1)

协程下载模板

  • import asyncio
    import time
    
    
    async def download(url):
    print(url,'下载开始')
    await asyncio.sleep(2)
    print(url,'下载结束')
    
    async def main():
    urls = [
    'www.a1.com',
    'www.a2.com',
    'www.a3.com',
    'www.a4.com',
    'www.a5.com',
    'www.a6.com',
    ]
    
    tasks = []
    for url in urls:
    d = asyncio.create_task(download(url))
    tasks.append(d)
    
    await asyncio.wait(tasks)
    
    if __name__ == '__main__':
    t1 = time.time()
    asyncio.run(main())
    t2 = time.time()
    print('所需时间:', t2 - t1)

协程下载实战

  • import asyncio
    import aiohttp
    import time
    
    async def download(url):
    name = url.rsplit('/', 1)[1]
    async with aiohttp.ClientSession() as session:
    async with session.get(url) as req:
    # 请求回来了,写入文件
    with open(name,'wb') as fp:
    #读取内容是异步的,需要await挂起
    fp.write(await req.content.read())
    print(name,'下载完成!')
    
    async def main():
    urls = [
    'https://pic.quanjing.com/c6/cx/QJ6880697447.jpg',
    'https://pic.quanjing.com/3g/lv/QJ6594284520.jpg',
    'https://pic.quanjing.com/ng/wd/QJ8166536175.jpg',
    'https://pic.quanjing.com/hj/jj/QJ6802044841.jpg',
    'https://pic.quanjing.com/tn/6t/QJ9127562743.jpg',
    'https://pic.quanjing.com/39/uc/QJ7108531848.jpg',
    ]
    
    tasks = []
    for url in urls:
    d = asyncio.create_task(download(url))
    tasks.append(d)
    
    await asyncio.wait(tasks)
    
    if __name__ == '__main__':
    t1 = time.time()
    #asyncio.run(main()) 会报错
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    
    t2 = time.time()
    print('所需时间:', t2 - t1)

赞 (0)

猜您想看

评论区(暂无评论)

这里空空如也,快来评论吧~

我要评论