yield函数在并发编程中是非常重要的一个概念,尤其在多核计算机还不是那么普及的年代,要完成一个“并发”程序,是不得不借助yield函数的。
我们知道,yield的意思是“屈服、礼让”,在程序中表现为当前线程会尽量让出CPU资源来给其他线程执行,但是yield函数背后究竟发生了什么呢,我们结合线程、栈来说明函数背后是如何执行,程序是如何配合CPU来完成yield函数的。

首先我们来看一个例子,

100:A(){B();104:...
}
200:B(){yield();204:...
}300:C(){D();304:...
}
400:D(){yield();404:...
yeald(){找到 ?;jump ?;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

上面一段代码,整体说明:A(),B()为一个线程在执行,C(),D()为另一个线程在执行,在执行到B()函数的时候,调用yield从a线程跳到b线程执行,执行到D()函数的时候,又调用yield返回a线程继续执行。
如果我们这样设计行不行呢?

两个线程公用一个栈:pc指到100,a线程进入A()函数开始执行,进入B()函数之前将指针104压栈,B函数刚执行就遇到yield函数,将204压栈,a线程停止执行,yield给b线程开始执行,进入C函数,将304压栈后进入D(),进入D遇到yield函数则将404压栈。注意,此时yield函数我们的本意是希望调回到a线程仅需执行204,此时弹栈,弹出404,这就不对了,我们不是要执行204吗?
可以看到两个线程公用一个栈,使用yield函数是无法完成我们想要的效果的。设计者们意识其实线程在进程中的模型和进程在操作系统中的模型在某些方面是由一些相似的,一个线程应该对应一个栈与其他线程隔离就像一个进程对应一块隔离的内存区域一样,如果这样当我们从a线程跳到b线程执行的时候,如果需要跳回来则CPU需要在跳过去的时候记录a线程的相关信息执行完b线程后才能通过相关信息再跳回a线程来执行,这不是和我们学习过的PCB(process control block)非常相似吗?

多个线程维护各自的栈,这是一个非常伟大的过渡,让很多线程操作都变得清晰起来。

yield(){TCB2.esp = esp;esp = TCB1.esp;
}

上面这个yield的函数才是真正从b线程跳回a线程执行的操作,我们通过栈操作来屡清执行的顺序。Thread control block 线程控制块,可以理解为由进程来进行管理的一种数据结构,这个数据结构中有线程的相关信息,其中一个字段为esp,它是当前线程的栈指针。回到上面的函数中,esp是CPU寄存器的指针指向的位置,可以看到,yield函数其实就是把当前CPU执行的线程的栈保存起来,并且取出需要执行的线程的栈指针,赋给寄存器开始执行。
现在就显而易见了,当a线程跳到b线程的时候,a线程的栈中104 204先后压栈,跳到b线程后304 405先后压入当前线程的栈中,又通过切换寄存器的栈指针跳回到a线程中来执行,此时弹栈,继续执行204,一切是那么完美!
尔后,每个线程中的地址和变量不断出入栈、线程不断的切来切去,这样就完成了我们设计的“并发”程序!

yield( )函数的使用相关推荐

  1. c++11 yield函数的使用

    yield函数时c++11的新特性,它在std::this_thread::yield命名空间中实现,函数声明如下: void yield() noexcept; 其作用是当前线程"放弃&q ...

  2. Arduino ESP8266当中的yield 函数

    Arduino ESP8266当中的yield() 函数 在库函数中yield()函数相关代码: 通过VSCode PIO,我的文件位置在:C:\Users\Administrator\.platfo ...

  3. yield()函数的使用

    yield函数在并发编程中是非常重要的一个概念,尤其在多核计算机还不是那么普及的年代,要完成一个"并发"程序,是不得不借助yield函数的. 我们知道,yield的意思是" ...

  4. 【Kotlin 协程】协程取消 ② ( CPU 密集型协程任务取消 | 使用 isActive 判定协程状态 | 使用 ensureActive 函数取消协程 | 使用 yield 函数取消协程 )

    文章目录 一.CPU 密集型协程任务取消 二.使用 isActive 判定当前 CPU 密集型协程任务是否取消 三.使用 ensureActive 自动处理协程退出 四.使用 yield 函数检查协程 ...

  5. python yield函数的用法

    什么是yield函数? yield函数是python里面的关键字,带有yield的函数相当于一个生成器generator.当你使用一个yield的时候,对应的函数就是一个生成器 在python里面类似 ...

  6. arduino yield函数的作用_Python里Yield关键词的作用

    要理解yield的作用,您必须理解生成器是什么.在理解生成器之前,必须先理解迭代器. 迭代器 当您创建一个列表时,您可以逐个读取它的项.逐项读取其项称为迭代: >>> mylist ...

  7. yield 函数的理解

    yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始 首先,如果你还没有对yield有个初步分认识,那么你先把yield看做"return" ...

  8. yield函数c语言,yield的用法

    我来解释一下这个程序: 首先大家要知道为什么这个函数可以用在for循环中.不用问,因为这个函数是可迭代的,也就是这个函数可以每次都返回一个值. 但是我们在gen()函数里看不到__iter__()和n ...

  9. arduino yield函数的作用_深入理解yield

    yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法. 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: def addlist( ...

最新文章

  1. 收藏 | Google 发布关于机器学习工程的最佳实践
  2. iptables规则备份和恢复,任务计划chkconfig工具systemd管理服务
  3. 什么是OOA/OOD
  4. 笔记36 Spring Web Flow——配置
  5. android v4包自动导入吧,android如何导入v4包的源码
  6. 获奖名单出炉,快来看看有没有你!
  7. git远程仓库的使用
  8. DataGridView控件机制及使用大全
  9. 3 天开发物联网应用!腾讯云 IoT 超级小程序来了
  10. L1-009. N个数求和-PAT团体程序设计天梯赛GPLT
  11. Linux系统中用stat命令查看文件的三个时间属性
  12. (转)Palantir: 神秘的大数据公司
  13. 【白话区块链】面向区块链开发
  14. 安全工具(免费杀毒软件Avast、免费防火墙费尔、免费木马清理工具arswp,AVG/Ewido,超级兔子)...
  15. 计算机四分位数公式,上四分位数(上下四分位数计算公式)
  16. (bat)检查今天星期几,并执行程序
  17. 华硕主板无盘启动bios设置_华硕主板怎么进入bios?华硕主板进入bios设置u盘启动方法...
  18. cocos2d关于延时的实现
  19. 【转】PS学堂之一:展示一下自己做的圆形印章
  20. 干货 | 软件工程师必知之事 —— 如何定义自己的职业路线?

热门文章

  1. 2020年人工神经网络第二次作业
  2. python中继承是什么意思_如何理解Python中的继承?python入门
  3. python中计算如何实现_如何实现计算每个函数的梯度?
  4. php7.2 mysql 教程_如何在PHP7中扩展mysql,先安装php7.2。后安装mysql
  5. c++两个vector合并_这才是真正的 Git:分支合并
  6. python实现数据库连接池_Python实现Mysql数据库连接池
  7. vscode 补全功能,和函数跳转
  8. php window.onload,window.onload 触发时机问题
  9. python秒表游戏代码_用20行Python代码实现2048小游戏,你会吗?
  10. vxworks linux 多线程api,vxWorks多任务编程初探(转)