yield核心实现(yield函数怎么使用c语言实现)

2026-04-12 04:00:01 0

yield核心实现(yield函数怎么使用c语言实现)

这篇文章给大家聊聊关于yield核心实现,以及yield函数怎么使用c语言实现对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

本文目录

yield函数怎么使用c语言实现

函数是一个对象,继承自FuctionN,函数对象有curried,equals,isInstanceOf,toString这些方法。 而方法不具有这些特性。如果想把方法转换成一个函数,可以用方法名跟上下划线的方式.

详解Python中的协程,为什么说它的底层是生成器

协程又称为是微线程,英文名是Coroutine。它和线程一样可以调度,但是不同的是线程的启动和调度需要通过操作系统来处理。并且线程的启动和销毁需要涉及一些操作系统的变量申请和销毁处理,需要的时间比较长。而协程呢,它的调度和销毁都是程序自己来控制的,因此它更加轻量级也更加灵活。

协程有这么多优点,自然也会有一些缺点,其中最大的缺点就是需要编程语言自己支持,否则的话需要开发者自己通过一些方法来实现协程。对于大部分语言来说,都不支持这一机制。go语言由于天然支持协程,并且支持得非常好,使得它广受好评,短短几年时间就迅速流行起来。

对于Python来说,本身就有着一个GIL这个巨大的先天问题。GIL是Python的全局锁,在它的限制下一个Python进程同一时间只能同时执行一个线程,即使是在多核心的机器当中。这就大大影响了Python的性能,尤其是在CPU密集型的工作上。所以为了提升Python的性能,很多开发者想出了使用多进程+协程的方式。一开始是开发者自行实现的,后来在Python3.4的版本当中,官方也收入了这个功能,因此目前可以光明正大地说,Python是支持协程的语言了。

生成器(generator)

生成器我们也在之前的文章当中介绍过,为什么我们介绍协程需要用到生成器呢,是因为Python的协程底层就是通过生成器来实现的。

通过生成器来实现协程的原因也很简单,我们都知道协程需要切换挂起,而生成器当中有一个yield关键字,刚好可以实现这个功能。所以当初那些自己在Python当中开发协程功能的程序员都是通过生成器来实现的,我们想要理解Python当中协程的运用,就必须从最原始的生成器开始。

生成器我们很熟悉了,本质上就是带有yield这个关键词的函数。

def test():

    n = 0

    while n 《 10:

        val = yield n 

        print(’val = {}’.format(val))

        n += 1

这个函数当中如果没有yield这个语句,那么它就是一个普通的Python函数。加上了val = yield n这个语句之后,它有什么变化呢?

我们尝试着运行一下:

# 调用test函数获得一个生成器

g = test()

print(next(g))

print(next(g))

print(next(g))

得到这么一个结果:

输出的0,1,2很好理解,就是通过next(g)返回的,这个也是生成器的标准用法。奇怪的是为什么val=None呢?val不应该等于n么?

这里想不明白是正常的,因为这里涉及到了一个新的用法就是生成器的send方法。当我们在yield语句之前加上变量名的时候,它的含义其实是返回yield之后的内容,再从外界接收一个变量。也就是说当我们执行next(g)的时候,会从获取yield之后的数,当我们执行g.send()时,传入的值会被赋值给yield之前的数。比如我们把执行的代码改成这样:

g = test()

print(next(g))

g.send(’abc’)

print(next(g))

print(next(g))

我们再来看执行的结果,会发现是这样的:

第一行val不再是None,而是我们刚刚传入的abc了。

队列调度

生成器每次在执行到yield语句之后都会自然挂起,我们可以利用这一点来当做协程来调度。我们可以自己实现一个简易的队列来模拟这个过程。

首先我们声明一个双端队列,每次从队列左边头部获取任务,调度执行到挂起之后,放入到队列末尾。相当于我们用循环的方式轮询执行了所有任务,并且这整个全程不涉及任何线程创建和销毁的过程。

class Scheduler:

    def __init__(self):

        self._queue = deque()

    def new_task(self, task):

        self._queue.append(task)

    def run(self):

        while self._queue:

            # 每次从队列左侧获取task

            task = self._queue.popleft()

            try:

                # 通过next执行之后放入队列右侧

                next(task)

                self._queue.append(task)

            except StopIteration:

                pass

sch = Scheduler()

sch.new_task(test(5))

sch.new_task(test(10))

sch.new_task(test(8))

sch.run()

这个只是一个很简易的调度方法,事实上结合上yield from以及send功能,我们还可以实现出更加复杂的协程调度方式。但是我们也没有必要一一穷尽,只需要理解最基础的方法就可以了,毕竟现在我们使用协程一般也不会自己实现了,都会通过官方原生的工具库来实现。

@asyncio.coroutine

在Python3.4之后的版本当中,我们可以通过@asyncio.coroutine这个注解来将一个函数封装成协程执行的生成器。

在吸收了协程这个概念之后,Python对生成器以及协程做了区分。加上了@asyncio.coroutine注解的函数称为协程函数,我们可以用iscoroutinefunction()方法来判断一个函数是不是协程函数,通过这个协程函数返回的生成器对象称为协程对象,我们可以通过iscoroutine方法来判断一个对象是不是协程对象。

比如我把刚刚写的函数上加上注解之后再来执行这两个函数都会得到True:

import asyncio

@asyncio.coroutine

def test(k):

    n = 0

    while n 《 k:

        yield

        print(’n = {}’.format(n))

        n += 1

        print(asyncio.iscoroutinefunction(test))

print(asyncio.iscoroutine(test(10)))

那我们通过注解将方法转变成了协程之后,又该怎么使用呢?

一个比较好的方式是通过asynio库当中提供的loop工具,比如我们来看这么一个例子:

loop = asyncio.get_event_loop()

loop.run_until_complete(test(10))

loop.close()

我们通过asyncio.get_event_loop函数创建了一个调度器,通过调度器的run相关的方法来执行一个协程对象。我们可以run_until_complete也可以run_forever,具体怎么执行要看我们实际的使用场景。

async,await和future

从Python3.5版本开始,引入了async,await和future。我们来简单说说它们各自的用途,其中async其实就是@asyncio.coroutine,用途是完全一样的。同样await代替的是yield from,意为等待另外一个协程结束。

我们用这两个一改,上面的代码就成了:

async def test(k):

    n = 0

    while n 《 k:

        await asyncio.sleep(0.5)

        print(’n = {}’.format(n))

        n += 1

由于我们加上了await,所以每次在打印之前都会等待0.5秒。我们把await换成yield from也是一样的,只不过用await更加直观也更加贴合协程的含义。

Future其实可以看成是一个信号量,我们创建一个全局的future,当一个协程执行完成之后,将结果存入这个future当中。其他的协程可以await future来实现阻塞。我们来看一个例子就明白了:

future = asyncio.Future()

async def test(k):

    n = 0

    while n 《 k:

        await asyncio.sleep(0.5)

        print(’n = {}’.format(n))

        n += 1

    future.set_result(’success’)

async def log():

    result = await future

    print(result)

loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait([

    log(),

    test(5)

]))

loop.close()

在这个例子当中我们创建了两个协程,第一个协程是每隔0.5秒print一个数字,在print完成之后把success写入到future当中。第二个协程就是等待future当中的数据,之后print出来。

在loop当中我们要调度执行的不再是一个协程对象了而是两个,所以我们用asyncio当中的wait将这两个对象包起来。只有当wait当中的两个对象执行结束,wait才会结束。loop等待的是wait的结束,而wait等待的是传入其中的协程的结束,这就形成了一个依赖循环,等价于这两个协程对象结束,loop才会结束。

总结

async并不只是可以用在函数上,事实上还有很多其他的用法,比如用在with语句上,用在for循环上等等。这些用法比较小众,细节也很多,就不一一展开了,大家感兴趣的可以自行去了解一下。

不知道大家在读这篇文章的过程当中有没有觉得有些费劲,如果有的话,其实是很正常的。原因也很简单,因为Python原生是不支持协程这个概念的,所以在一开始设计的时候也没有做这方面的准备,是后来觉得有必要才加入的。那么作为后面加入的内容,必然会对原先的很多内容产生影响,尤其是协程借助了之前生成器的概念来实现的,那么必然会有很多耦合不清楚的情况。这也是这一块的语法很乱,对初学者不友好的原因。

OK,关于yield核心实现和yield函数怎么使用c语言实现的内容到此结束了,希望对大家有所帮助。

yield核心实现(yield函数怎么使用c语言实现)

本文编辑:admin

更多文章:


变形金刚完整历史(变形金刚是什么时候诞生的)

变形金刚完整历史(变形金刚是什么时候诞生的)

大家好,变形金刚完整历史相信很多的网友都不是很明白,包括变形金刚是什么时候诞生的也是一样,不过没有关系,接下来就来为大家分享关于变形金刚完整历史和变形金刚是什么时候诞生的的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!本

2025年12月25日 12:45

previous的短语(以前的,先前的英文)

previous的短语(以前的,先前的英文)

其实previous的短语的问题并不复杂,但是又很多的朋友都不太了解以前的,先前的英文,因此呢,今天小编就来为大家分享previous的短语的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!本文目录以前的,先前的英文“早先

2025年12月18日 06:00

activitythread工作原理(ViewModel的原理)

activitythread工作原理(ViewModel的原理)

其实activitythread工作原理的问题并不复杂,但是又很多的朋友都不太了解ViewModel的原理,因此呢,今天小编就来为大家分享activitythread工作原理的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧

2026年5月26日 05:00

substr函数的功能(substr函数怎么用)

substr函数的功能(substr函数怎么用)

各位老铁们好,相信很多人对substr函数的功能都不是特别的了解,因此呢,今天就来为大家分享下关于substr函数的功能以及substr函数怎么用的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录substr函数怎

2025年9月18日 18:00

maven配置文件放哪里(maven打包时如何把包下面的XML配置文件也包含)

maven配置文件放哪里(maven打包时如何把包下面的XML配置文件也包含)

大家好,maven配置文件放哪里相信很多的网友都不是很明白,包括maven打包时如何把包下面的XML配置文件也包含也是一样,不过没有关系,接下来就来为大家分享关于maven配置文件放哪里和maven打包时如何把包下面的XML配置文件也包含的

2025年9月12日 17:30

compensation 单词(compensation同义词)

compensation 单词(compensation同义词)

“compensation 单词”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看compensation 单词(compensation同义词)!本文目录compensation同义词C单词中的ion后缀compensati

2025年9月10日 19:15

carry网络用语(c指的是什么意思啊)

carry网络用语(c指的是什么意思啊)

大家好,carry网络用语相信很多的网友都不是很明白,包括c指的是什么意思啊也是一样,不过没有关系,接下来就来为大家分享关于carry网络用语和c指的是什么意思啊的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!本文目录c

2026年3月10日 23:15

boards翻译(主板英文怎么说)

boards翻译(主板英文怎么说)

大家好,boards翻译相信很多的网友都不是很明白,包括主板英文怎么说也是一样,不过没有关系,接下来就来为大家分享关于boards翻译和主板英文怎么说的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!本文目录主板英文怎么说

2025年7月28日 15:30

mentality是什么意思(victim mentality是什么意思)

mentality是什么意思(victim mentality是什么意思)

大家好,今天小编来为大家解答以下的问题,关于mentality是什么意思,victim mentality是什么意思这个很多人还不知道,现在让我们一起来看看吧!本文目录victim mentality是什么意思village mentali

2026年1月13日 09:00

microchip单片机有什么不同(Microchip、NXP、Fujitsu、Texas Instruments、Freescale 、STC几家单片机厂商各自特点及应用领域)

microchip单片机有什么不同(Microchip、NXP、Fujitsu、Texas Instruments、Freescale 、STC几家单片机厂商各自特点及应用领域)

大家好,如果您还对microchip单片机有什么不同不太了解,没有关系,今天就由本站为大家分享microchip单片机有什么不同的知识,包括Microchip、NXP、Fujitsu、Texas Instruments、Freescale

2026年9月20日 07:15

css样式工具(css样式只能修改不能删除)

css样式工具(css样式只能修改不能删除)

本篇文章给大家谈谈css样式工具,以及css样式只能修改不能删除对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录css样式只能修改不能删除w

2026年1月23日 18:30

redistributable x86(Microsoft Visual C++ 2015 Redistributable x86是系统自带的吗)

redistributable x86(Microsoft Visual C++ 2015 Redistributable x86是系统自带的吗)

各位老铁们,大家好,今天由我来为大家分享redistributable x86,以及Microsoft Visual C++ 2015 Redistributable x86是系统自带的吗的相关问题知识,希望对大家有所帮助。如果可以帮助到大

2025年7月24日 10:15

企业网站建设有哪些好处?企业网站建设的优势、好处是什么

企业网站建设有哪些好处?企业网站建设的优势、好处是什么

今天给各位分享企业网站建设有哪些好处的知识,其中也会对企业网站建设有哪些好处进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录企业网站建设有哪些好处企业网站建设的优势、好处是什么最常见企业网站公司有哪些企业网站建

2025年7月4日 21:00

readprocessmemory(U盘出现仅完成部分的ReadProcessMemory 或WriteProcessMemory请求)

readprocessmemory(U盘出现仅完成部分的ReadProcessMemory 或WriteProcessMemory请求)

大家好,如果您还对readprocessmemory不太了解,没有关系,今天就由本站为大家分享readprocessmemory的知识,包括U盘出现仅完成部分的ReadProcessMemory 或WriteProcessMemory请求的

2025年10月5日 22:00

power query拆分列的拆分依据(在wps或excel里面,在一段文本里面把两个数字按大小挑出来)

power query拆分列的拆分依据(在wps或excel里面,在一段文本里面把两个数字按大小挑出来)

大家好,今天小编来为大家解答以下的问题,关于power query拆分列的拆分依据,在wps或excel里面,在一段文本里面把两个数字按大小挑出来这个很多人还不知道,现在让我们一起来看看吧!本文目录在wps或excel里面,在一段文本里面把

2025年12月4日 07:15

according to legend(英语作文关于历史人物 少于100字数)

according to legend(英语作文关于历史人物 少于100字数)

本篇文章给大家谈谈according to legend,以及英语作文关于历史人物 少于100字数对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本

2026年7月3日 01:15

java数组的长度怎么看(java中如何判断一个数组的长度呢比如我申请了一个数组int [] arr = new int[8];)

java数组的长度怎么看(java中如何判断一个数组的长度呢比如我申请了一个数组int [] arr = new int[8];)

这篇文章给大家聊聊关于java数组的长度怎么看,以及java中如何判断一个数组的长度呢比如我申请了一个数组int [] arr = new int[8];对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。本文目录java中如何判断一个数

2025年6月23日 17:30

deserts怎么读(deserts怎么读)

deserts怎么读(deserts怎么读)

本篇文章给大家谈谈deserts怎么读,以及deserts怎么读对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录deserts怎么读dese

2026年3月15日 02:15

mysql与大数据(mysql怎么处理大数据)

mysql与大数据(mysql怎么处理大数据)

各位老铁们好,相信很多人对mysql与大数据都不是特别的了解,因此呢,今天就来为大家分享下关于mysql与大数据以及mysql怎么处理大数据的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录mysql怎么处理大数据

2026年8月23日 08:15

excel函数总和(excel求和函数是什么)

excel函数总和(excel求和函数是什么)

其实excel函数总和的问题并不复杂,但是又很多的朋友都不太了解excel求和函数是什么,因此呢,今天小编就来为大家分享excel函数总和的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!本文目录excel求和函数是什么e

2025年12月10日 08:30

近期文章

char ch用法(c语言char ch)
2026-09-24 18:45:02
本站热文

electronics软件(labcenter electronics是什么软件)
2025-05-22 23:45:02 浏览:134
博客是微博吗(博客是微博吗)
2025-05-22 22:45:01 浏览:111
diversity and distribution(悬赏英语短文)
2025-05-23 16:15:02 浏览:107
ios软件开发前景(iOS就业前景怎么样)
2025-05-22 23:00:01 浏览:102
next month(有The next month这个单词吗,和 next month有什么区别)
2025-05-23 02:30:01 浏览:102
patron(patron是什么意思)
2025-05-23 10:30:02 浏览:95
标签列表

热门搜索