Python - 进程、线程与协程

在操作系统中,每一个独立运行的程序,都占有 操作系统 分配的资源,这些程序中间互不干涉,都只负责运行自己的程序代码,这就是进程。

但是当操作系统频繁的创建销毁进程时,大量的系统资源被浪费在创建和销毁的过程中。而随着多核心 cpu 的出现,线程也逐渐代替了进程,成为了操作系统 可以独立运行的基本单位。

当进程不是多线程程序时,存在于进程当中的唯一线程,便是进程本身运行的代码块。

而当多线程出现在一个进程中时,则多个线程之间共享此进程的资源,并接受操作系统的调度来运行每个线程。

状态

协程

为了了解协程的概念,我们先来了解一下并发和并行。

并行

并行比较好理解,即有多个程序在同时执行,这里的程序指的是操作系统的线程。

每个 cpu 核心,只能在同一个时刻运行一组指令,意味着同一时刻,一个核心上只有一个线程在执行。

当 cpu 有四个核心时,他只可以 执行4个线程。

并发

想要了解并发,就需要知道 和 。

同步阻塞

当程序中的一个 I/O 操作,会占据比较长的时间,这时候,程序没有被挂起,且一直在等待网络数据传输,无法进行其他操作,这时候就是同步阻塞。

同步的一个概念就是,网络传输完成后也无法告知主程序操作完成,这就导致了主程序:

  • 要么只能进行等待 I/O 完成
  • 要么轮询去查看是否传输是否已经完成

当然,轮询时候可以进行其他的操作,这时候,就是非阻塞的状态,即 同步非阻塞。

同步非阻塞

非阻塞的概念即主程序可以进行其他的操作。

异步阻塞

有同步,就有异步。

而异步阻塞与同步阻塞相同,主程序啥也不干,就等着 I/O 操作完成。

异步非阻塞

异步非阻塞状态,便是并发的关键。

当主程序使用异步 I/O 操作时,并不会影响主程序后续的运行,而当异步 I/O 操作完成后,会主动通知主程序进行其他操作,这样就减少了轮询过程中的资源消耗,专注于其他工作。

并发

而并发就是 异步非阻塞 状态下的一种形式,当程序执行操作 a 时,使 a 的 I/O 异步操作,这时程序去执行操作 b, 在外部看来,a 和 b 时同时被执行的,然而他们只运行在在一个线程当中。

与线程、进程不同的是,协程并不是操作系统物理层面存在的一种程序。

协程是程序级别的,由程序编写者自己操控整个协程的生命周期。这样就实现了类似操作系统操作多线程一样的效果,但是省下了现成的切换中造成的资源消耗。

而通过程序来操纵协程,就造成了cpu 一直在运行,并且是多个协程一直在运行的假象,也就变成了并发。

实例

下面我们通过几个实例来说明,在 python 中的进程、线程和协程的关系。

进程实例

在 python 中我们如何编写多进程的程序呢?

答案是使用模块 multiprocessing 进行实现。

import timefrom multiprocessing import Processclass Test(Process): def __init__(self): super().__init__() def run(self): while True: print('process b is run') time.sleep(1)

通过继承 multiprocessing 的 Process ,实现进程类,然后实现 run 方法,即可在此方法中实现进程要运行的内容。

from process_b import Testimport timeif __name__ == '__main__':    t = Test()    t.start()    while True:        print('process a run')        time.sleep(1)

调用方法也非常简单,直接使用 Test 实例化对象,然后调用对象的成员函数 start() 即可。

python3 process_a.pyprocess a runprocess b is runprocess b is runprocess a runprocess a runprocess b is runprocess b is runprocess a run

线程实例

Cpython 中由于存在 GIL ,所以多线程在实际应用中也会变为单核 cpu 上的线程,排队运行。

import threadingimport timeclass ThreadTest (threading.Thread):    def __init__(self, name):        super().__init__()        self.name = name    def run(self):        while True:            print(f'i am in thread {self.name}')            time.sleep(1)if __name__ == '__main__':    threads = []    for i in range(4):        t = ThreadTest(i)        threads.append(t)        for t in threads:        t.start()        for t in threads:        t.join()

通过继承 threading.Thread 来实现线程类,然后通过实例化,生成对象,调用对象的 start() 即可启动线程。

运行结果

python3 thread_a.pyi am in thread 0i am in thread 1i am in thread 2i am in thread 3i am in thread 1i am in thread 3i am in thread 0i am in thread 2i am in thread 1i am in thread 3i am in thread 0i am in thread 2i am in thread 1

协程

python3 将 asyncio 加入到了标准库。

import asyncioimport timeasync def test(num):    await asyncio.sleep(num)    print(num)async def run():    tasks = [asyncio.create_task(test(num)) for num in range(4)]    [await t for t in tasks]def run_main():    asyncio.run(run())if __name__ == '__main__':    run_main()

运行结果

import asyncioimport timeasync def test(num): await asyncio.sleep(num) print(num)async def run(): tasks = [asyncio.create_task(test(num)) for num in range(4)] [await t for t in tasks]def run_main(): asyncio.run(run())if __name__ == '__main__': run_main()

总结

以上就是本节的所有内容,主要简单地讲解了关于 进程、线程和协程 的概念和例子。

(0)

相关推荐

  • Python进程与线程知识

    Python进程与线程知识,Python开发语言现在已经是被大家非常看中的编程语言了,本篇文章给读者们分享一下Python进程与线程知识小结,本篇文章具有一定的参考借鉴价值,感兴趣的小伙伴来了解一下吧 ...

  • 总算搞明白了!进程,线程,协程,生成器,迭代器搞的我脑子好乱!

    你是否曾经被迭代器,生成器,进程,线程,协程搞的脑子很乱? 而且剪不断,理还乱: 这不怪你,这是有历史原因.本文试图把东西都给理顺了. 一篇不行,咱们就再来一篇,使劲点赞. 两个问题,三种协程 先来看 ...

  • 简单明了的 Python 多线程来了

    线程和进程   计算机的核心是CPU,它承担了所有的计算任务,就像是一座工厂在时刻运行. 如果工厂的资源有限,一次只能供一个车间来使用,也就是说当一个车间开工时其它车间不能工作,也就是一个CPU一次只 ...

  • (1条消息) python多进程并发与pool多线程

    一.多进程: 当计算机运行程序时,就会创建包含代码和状态的进程.这些进程会通过计算机的一个或多个CPU执行.不过,同一时刻每个CPU只会执行一个进程,然后不同进程间快速切换,给我们一种错觉,感觉好像多 ...

  • python 多线程知识全面解析

    Python编程学堂 4天前 非阻塞启动线程 import threadingimport timedef one_thread(name,id): print("start....&quo ...

  • python笔记11-多线程之Condition(条件变量)

    前言 当小伙伴a在往火锅里面添加鱼丸,这个就是生产者行为:另外一个小伙伴b在吃掉鱼丸就是消费者行为.当火锅里面鱼丸达到一定数量加满后b才能吃,这就是一种条件判断了. 这就是本篇要讲的Condition ...

  • 用一个开源工具实现多线程 Python 程序的可视化 | Linux 中国

    原创 邀你一起成为开源贡献者 Linux中国   导读:VizTracer 可以跟踪并发的 Python 程序,以帮助记录.调试和剖析. 本文字数:4686,阅读时长大约:6分钟 https://li ...

  • RTOS中的任务是线程、进程、还是协程?

    今天为大家讲解讲解OS中的线程.进程和协程的这几个概念,同时一起看看RTOS中的任务到底属于哪一种. 1.三者整体关系图 很多小伙伴在学习OS的过程中会遇到各种程序形态,比如说进程.线程.协程.管程. ...

  • 一文读懂什么是进程、线程、协程(建议收藏)

    进程 我们都知道计算机的核心是CPU,它承担了所有的计算任务:而操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:应用程序则是具有某种功能的程序,程序是运行于操作系统之 ...

  • 纯干货|一文讲透 “进程、线程、协程”

    本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什么? 为什么说Python中的多线程是伪多线程? 不同的应用场景该如何选择技术方案? ... 什么是进程 ...

  • 深入分析 Java、Kotlin、Go 的线程和协程

    前言 协程是什么 协程的好处 进程 进程是什么 进程组成 进程特征 线程 线程是什么 线程组成 任务调度 进程与线程的区别 线程的实现模型 一对一模型 多对一模型 多对多模型 线程的"并发& ...

  • 多路复用、非阻塞、线程与协程

    线程与阻塞 在传统的 blockIO 中,一个 TCP 连接的可读事件与用户的实际读取操作是糅合在一起的.用户想要读取数据只需要调用 read 系统调用,之后当前线程会阻塞在这里直到当前连接的读缓冲区 ...

  • (1条消息) python3爬虫系列14之进程、单进程、多进程、线程、单线程、多线程、并行、并发、互斥锁、协程的白话解释

    python3爬虫系列14之进程.单进程.多进程.线程.单线程.多线程.并行.并发.互斥锁.协程的白话解释 1. 前言回顾 到目前为止,实际上我们的爬虫进程总共介绍了: 爬虫架构--确认目标(爬虫对象 ...

  • gevent-使用greenlet的基于协程的Python网络库

    什么是 gevent? gevent 是一个基于协程的Python网络库,它使用 greenlet在libev 或libuv事件循环之上提供高级同步 API . 功能包括: 基于libev或libuv ...