控制结构(7) 程序计数器(PC)
// 上一篇:最近最少使用(LRU)
// 下一篇:线性化(linearization)
程序的每一行都是一个状态,对应的行指令。同步的情况下同一个pc一直自增,异步的时候,分裂出一个新的子pc,独立一颗子状态机。之所以要分裂一个pc是因为原来的pc后续的同步代码要用,而创建协程就会一开始就创建出一个新pc,这个pc专为协程里的状态机服务,则协程可以在异步点随时yield,也就是暂存独立的pc,跳转到旧pc去执行,然后再resume到新pc这里。基本上,就是两个状态机之间轮流占用时间片。一个独立的状态机一个pc,在同一个pc上的状态机片段,就可以在这个pc所代表的时间线上流式串起来,这就是所谓的react programming的原理,一个pc上面的流,就可以通过parser做filter,进而做成独立的pipeline.
多进程下,每个进程有独立id,每个进程的堆栈是独立的。
在多线程里,每个线程有独立的id,每个线程有独立的local storage,于是,调试器可以通过线程id和线程局部存储来标记不同线程上的调用链。因此,可以为不同的线程产生独立的函数调用堆栈,因为调试器可以把不同线程的函数调用链区分开来。
单线程里,一个函数的两次调用,他们的外围作用域是同一个,通过同一个外围作用域,一个函数的两次调用之间共享全局变量。同一个函数的两次调用所引发的后续调用链条,如果要区分开,需要各自一个独立的ID(类似上一段的pc),比如,在调用链条上到处传递这个ID可以做到。那么,有没有办法不显式传递这个ID,直接通过全局变量拿到呢?
一般来说是有困难的,假设使用一个全局变量标记函数一次调用的id,在该函数第二次调用的时候,id要变,但是如果你直接改变同一个全局变量,则上一次调用链里拿到的该id就被修改了。所以,必需函数的每次调用都有一个独立的id变量来标记。那么问题来了,在函数调用链条中,怎样拿到自己的那次调用的id变量?
由于一般语言并没有基础设施标记函数在动态之行中的独立调用标记,没有办法区分开应该拿第几个id变量。如果一个语言能支持函数执行过程中动态获取自己所在调用链的独立id,那就是一个很赞的语言。协程(corotine)提供了一种这方面的支持,一个独立的协程所引发的调用链,可以取到当前协程,挂载在当前协程下的变量就是协程所在的「local storage」。
这样调试器又有机会把所有的协程区分开来,可以为每个协程产生独立的调用链条。
我为什么要从进程->多线程->单线程这样绕一圈分析呢?因为,存在另一个更本质的问题:
怎样在多进程情况下,多进程之间的一个调用链条串起来。
显而易见的方案:
在所有的调用链条上传id,显然,这样的做法可以满足需求,但是所有的调用接口都需要知道这个id参数。做法2:
在进程出口和入口处传id,进程内部用独立的线程跑每一次的独立调用链条,通过唯一线程id来区分,线程里执行的代码只需从当前线程局部存储就可以拿到当前调用链id,这样不需要在线程内部不需要到处传id,只在进程之间出口和入口传id。但问题也明显:我们不可能无限创建线程。于是考虑3:
在进程出口和入口处传id,进程内部采用独立的协程跑每一次的独立调用链条,通过唯一协程id来区分,协程里执行的代码只需从当前协程局部存储就可以拿到当前调用链id,这样不需要在协程内部到处传id,只需在进程之间出口和入口传id。
很好,第3种方案是可行的,只需要你的语言支持协程。这样我们就可以在多进程之间的调用链条上有每次调用的独立id(也就是pc,程序计数器)。通过这一个id,可以给这样的调用链实现调试器。取代已经落后的基于单线程函数调用栈的调试器。
在不支持协程的语言里怎么办?考虑一种弱化的方式:函数闭包+支持函数内写任意代码(嵌套的class、嵌套的function,嵌套的import、include等加载其他模块代码等接口)。一个支持闭包的函数,函数闭包范围内的代码都可以访问函数的参数变量。这个函数的参数变量就是这个函数闭包范围内代码一次执行的「local storage」,此时方案改进为:
- 在进程出口和入口处传id,进程内通过函数闭包的方式执行用户代码(把这个外围的大闭包函数称为scope-function),用户代码可以通过函数参数变量获取当前调用链条的id。
- 由于这个函数闭包内的代码都可以访问到这个scope-function的参数,因此scope-funciton内部的代码不需要到处传id),那么一个问题是,scope-function内的代码如果import另一个模块的代码,不就超出当前scope-function的范围了吗?
- 很简单,通过scope-function的参数,替换掉scope-function内部执行的import,这个import的实现里,我们只要把scope-function的局部存储用来做需要import的代码的新scope-function的参数即可。
- 用户代码仍然不需要到处传id。
程序计数器,古老术语的内涵。本文的核心是说明“用独立id串起动态执行的有序调用链条”,不是进程、线程、协程等已有设施。
控制结构(7) 程序计数器(PC)的更多相关文章
- 系统架构师考试——程序计数器 PC, 指令寄存器IR、状态寄存器SR、通用寄存器GR
● 计算机执行程序时,在一个指令周期的过程中,为了能够从内存中读指令操作码,首先是将__(9)___的内容送到地址总线上. (9)A.程序计数器PC B.指令寄存器IR C.状态寄存器SR ...
- 运行时数据区--程序计数器(PC Register)
程序计数器(PC Register) 这里的计数器(Program Counter Register)并非为广义上所指的物理寄存器,JVM中的PC寄存器(程序计数器)是对物理PC寄存器的一种抽象模拟, ...
- 控制结构(7): 程序计数器(PC)
// 上一篇:最近最少使用(LRU) // 下一篇:线性化(linearization) 程序的每一行都是一个状态,对应的行指令.同步的情况下同一个pc一直自增,异步的时候,分裂出一个新的子pc,独立 ...
- 关于程序计数器(PC)和条件控制转移 引起的性能差异
关于PC(程序计数器) 冯 ·诺伊曼计算机体系结构的主要内容之一就是“程序预存储,计算机自动执行”! 处理器要执行的程序(指令序列)都是以二进制代码序列方式预存储在计算机的存储器中,处理器将这些代码逐 ...
- java虚拟机-程序计数器PC Register
什么是程序计数器? 程序计数器是一块 较小 的内存空间,它可以看做是当前线程所执行的字节码的 行号指示器 :在虚拟机的概念模型里(仅仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解 ...
- Java内存区域之程序计数器--《深入理解Java虚拟机》学习笔记及个人理解(一)
Java虚拟机程序计数器 在书上的P39页 程序计数器干嘛的? 有了它,字节码解释器才可以知道下一条要执行的字节码指令是哪个. 无论是取下一条指令还是分支.循环.跳转.中断.线程恢复,都需要这个程序计 ...
- 大脸猫讲逆向之ARM汇编中PC寄存器详解
i春秋作家:v4ever 近日,在研究一些开源native层hook方案的实现方式,并据此对ARM汇编层中容易出问题的一些地方做了整理,以便后来人能有从中有所收获并应用于现实问题中.当然,文中许多介绍 ...
- 20155339平措卓玛 Exp1 PC平台逆向破解(5)M
20155339平措卓玛 Exp1 PC平台逆向破解(5)M 实践内容 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖 ...
- 单片机pc指针
单片机的PC是指程序计数器(Program Counter).程序计数器PC用于存放下一条将要执行的指令地址,是一个16位专用寄存器,不能通过MOV指令来操作,对用户来说是不可见的.当执行一条指令时, ...
随机推荐
- SQL优化二(Sql性能调优)
一·.前言:这篇博文内容非原创,是我们公司的架构师给我们做技术培训的时候讲的内容,我稍微整理了下,借花献佛.这篇博文只是做一个大概的科普介绍,毕竟SQL优化的知识太大了,几乎可以用一本书来介绍.另外, ...
- 记小白的一次基于vue+express+mongodb个人站开发
学了vue和node一段时间了,折腾了一些零零散散的小东西.马上大四了要出去找工作了,所以早就想搭一个个人站作为一次较为全面的总结.因为没有设计功底,界面设计使我这种强迫症患者苦不堪言.幸而到最后花了 ...
- 让 SVN (TortoiseSVN)提交时忽略指定目录
2013-06-23 更新 后来我使用属性来过滤,结果反而没有效果了,之后我再次尝试使用全局忽略样式设置:*/bin */obj */packages 结果又有效果了,奇怪了. ------- 由于我 ...
- Struts2学习笔记(三)——Action详解
Action是用于处理请求操作的,它是由StrutsPrepareAndExceuteFilter分发过来的. 1.Action的创建方式 1) POJO类(PlainOldJavaObjects简单 ...
- 怎样查看当前QQ的版本号是多少
怎样查看当前QQ的版本号是多少.. -------------- -------------
- composer安装报错Composer throws [ReflectionException] Class Fxp\Composer\AssetPlugin\Repository\NpmRepository does not exist
解决方法:删除C:\Users\Administrator\AppData\Roaming\Composer\vendor\fxp下的文件
- 7.20.01 java格式化输出 printf 例子
java格式化输出 printf 例子 importjava.util.Date; publicclassPrintf { publicstaticvoidmain(String[] args) { ...
- java web面试技巧,数据库面试,java web轻量级开发面试教程
我最近看到一本比较好的讲java web方面面试的书,java web轻量级开发面试教程. 其中不仅用案例和视频讲述了Spring MVC,Hibernate, ORM等方面的技巧,而且还实际讲到了面 ...
- vue-cli脚手架npm相关文件解读(1)webpack.base.conf.js
系列文章传送门: 1.build/webpack.base.conf.js 2.build/webpack.prod.conf.js 3.build/webpack.dev.conf.js 4.bui ...
- Servlet使用简介
Servlet的使用基本包含三个步骤: 1.继承HttpServlet 或实现Servlet 接口 (根据源码分析最终都是对servlet接口的实现) 2.配置地址: 配置web.xml 或者用注解的 ...