python系列——多线程之协程(并发/并行,可迭代->yield->协程)

1、什么是并发:

https://blog.csdn.net/qq_33290787/article/details/51790605

讲并发之前,要先看一张图:

  1. Concurrency,是并发的意思。并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序(或线程)之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。
  2. 微观角度:所有的并发处理都有排队等候,唤醒,执行等这样的步骤,在微观上他们都是序列被处理的,如果是同一时刻到达的请求(或线程)也会根据优先级的不同,而先后进入队列排队等候执行。
  3. 宏观角度:多个几乎同时到达的请求(或线程)在宏观上看就像是同时在被处理。
  4. 通俗点讲,并发就是只有一个CPU资源,程序(或线程)之间要竞争得到执行机会。图中的第一个阶段,在A执行的过程中B,C不会执行,因为这段时间内这个CPU资源被A竞争到了,同理,第二个阶段只有B在执行,第三个阶段只有C在执行。其实,并发过程中,A,B,C并不是同时在进行的(微观角度)。但又是同时进行的(宏观角度)。

2、什么是并行:

同样,在讲并行之前,要先看一张图:

  1. Parallelism,即并行,指两个或两个以上事件(或线程)在同一时刻发生,是真正意义上的不同事件或线程在同一时刻,在不同CPU资源呢上(多核),同时执行。
  2. 并行,不存在像并发那样竞争,等待的概念。
  3. 图中,A,B,C都在同时运行(微观,宏观)。

3、协程(处理并发)简介

协程的本质:

并发的本质:切换+保存状态。

协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。

4、可迭代Iterable、迭代器Iterator以及生成器Generator介绍

首先:这三者是不一样的!!!!

4.1、可迭代

其中可迭代对象有:字符串、list、dict、tuple、deque等,可以使用isinstance()判断对象是否是可迭代、是否是迭代器、是否是生成器。

可迭代对象可以用for来循环。

重要:

可迭代对象,是其内部实现了,__iter__ 这个魔术方法。
可以通过,dir()方法来查看是否有__iter__来判断一个变量是否是可迭代的。

4.2、迭代器(以可迭代为基础,比可迭代多了__next__()方法)

对比可迭代对象,迭代器其实就只是多了一个函数而已。就是__next__(),我们可以不再使用for循环来间断获取元素值。而可以直接使用next()方法来实现。

迭代器,是在可迭代的基础上实现的。要创建一个迭代器,我们首先,得有一个可迭代对象。
现在就来看看,如何创建一个可迭代对象,并以可迭代对象为基础创建一个迭代器。

注意:可以使用通过,dir()方法来查看是否有__next__来判断一个变量是否是迭代器的。

实例1,以可迭代对象为基础创建一个迭代器:

from collections.abc import Iterable, Iterator, Generator

class MyList(object):  # 定义可迭代对象类

    def __init__(self, num):
        self.end = num  # 上边界

    # 返回一个实现了__iter__和__next__的迭代器类的实例
    def __iter__(self):
        return MyListIterator(self.end)


class MyListIterator(object):  # 定义迭代器类

    def __init__(self, end):
        self.data = end  # 上边界
        self.start = 0

    # 返回该对象的迭代器类的实例;因为自己就是迭代器,所以返回self
    def __iter__(self):
        return self

    # 迭代器类必须实现的方法,若是Python2则是next()函数
    def __next__(self):
        while self.start < self.data:
            self.start += 1
            return self.start - 1
        raise StopIteration


if __name__ == '__main__':
    my_list = MyList(5)  # 得到一个可迭代对象
    print(isinstance(my_list, Iterable))  # True
    print(isinstance(my_list, Iterator))  # False
    # 迭代
    for i in my_list:
        print(i)

    my_iterator = iter(my_list)  # 得到一个迭代器
    print(isinstance(my_iterator, Iterable))  # True
    print(isinstance(my_iterator, Iterator))  # True

    # 迭代
    print(next(my_iterator))
    print(next(my_iterator))
    print(next(my_iterator))
    print(next(my_iterator))
    print(next(my_iterator))

结果:

0
1
2
3
4

True
False

True
True

0
1
2
3
4

实例2,以字符串可迭代创建迭代器:

from collections.abc import Iterator

aStr = 'abcd'  # 创建字符串,它是可迭代对象
aIterator = iter(aStr)  # 通过iter(),将可迭代对象转换为一个迭代器
print(isinstance(aIterator, Iterator))  # True
next(aIterator)  # a
next(aIterator)  # b
next(aIterator)  # c
next(aIterator)  # d

4.3、生成器(在迭代器的基础上实现了yield)

啥是yield?

yield 是什么东西呢,它相当于我们函数里的return。在每次next(),或者for遍历的时候,都会yield这里将新的值返回回去,并在这里阻塞,等待下一次的调用。正是由于这个机制,才使用生成器在Python编程中大放异彩。实现节省内存,实现异步编程。

创建生成器的方式1:使用列表生成式:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值