在并发程序中,由于超时、取消 *** 作或其他一些异常情况,往往需要通知其他goroutine,虽然可以使用channel来处理这些问题,但是会变得非常繁琐,而且不利于多级管理。
go使用Context来做解决方案。
Context接口包含4个方法
emptyCtx其实就是一个int类型的变量,实现了Context接口。
如其名,就是一个没有设置超时时间,不能取消,也不能存储键值对的Context。
emptyCtx用来作为context的根结点。
而我们通常不会直接使用emptyCtx,而是使用emptyCtx实例化的两个变量
valueCtx利用了context类型的变量来表示父节点context,继承了父context的所有信息。
valueCtx携带了一个键值对,实现了Value方法,所以可以在context上获取key对应的值,如果context不存在,会沿着父context向上查找
向context中添加键值对,并不是直接在原context上直接添加,而是创建一个新的valueCtx,将键值对添加在子节点上。
和valueCtx类似,也有父context,
newCancelCtx只是初始化了cancelCtx
propagateCancel建立当前节点与父节点的取消逻辑
1、如果父context已经取消了,就直接返回,因为父节点不可能再被取消了
2、监听信号done,如果接收到了就通知子context取消
3、如果找到父context,就挂在父context上
4、如果没有找到父context,也就是自身是根context,就启动一个goroutine监听信号
而调用的cancel方法,其实就是关闭通道及设置原因
timer声明了一个定时器,用于发送截止时间
而timerCtxcancel有些不一样,是关闭定时器的。
关于timerCtx还有一个方法
与WithDeadline类似,只不过是创建了一个过期时间的context
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了。而并发问题是绝大部分的程序员头疼的问题,
但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研究一下常见的并发和同步吧。
为了更好的理解并发和同步,我们需要先明白两个重要的概念:同步和异步
1、同步和异步的区别和联系
所谓同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到
返回的值或消息后才往下执行其它的命令。
异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回
值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。
同步在一定程度上可以看做是单线程,这个线程请求一个方法后就待这个方法给他回复,否则他不往下执行(死心眼)。
异步在一定程度上可以看做是多线程的(废话,一个线程怎么叫异步),请求一个方法后,就不管了,继续执行其他的方法。
同步就是一件事,一件事情一件事的做。
异步就是,做一件事情,不引响做其他事情。
例如:吃饭和说话,只能一件事一件事的来,因为只有一张嘴。
但吃饭和听音乐是异步的,因为,听音乐并不引响我们吃饭。
对于Java程序员而言,我们会经常听到同步关键字synchronized,假如这个同步的监视对象是类的话,那么
只有线程处理出错才会造成奔溃,简单举个例子,线程刷新控件,你用整个父容器去invork,invork有Begin和end,前提条件还需要你已经创建了句柄,当窗体启动后,系统还会在后台启动窗体重绘,这时候线程开启了子线程,如果他快过主线程启动,那么它就会报从不创建句柄的控件更新ui错误,你不抛出强行执行,就会造成系统奔溃。所以控件少用invork,传值用传值对象去Post,界面使用传值方法,回调你要做接口。另一个典型的错误来自于,你创建了N个子线程,你不确定它到底有没有全部完成,主线程干掉了,对不起,子线程还没完呢?你都不处理一下,也不abort也不kill,程序就会溢出奔溃周期性奔溃你用计时器,子线程没有闭环,直接new一个对象然后直接start,就没有处理abort机制,它能不奔溃吗?有些ui刷新动作,你不注意句柄和控件和容器的关系,它绝对也是要奔溃的。
以上就是关于并发编程之协程调度context全部的内容,包括:并发编程之协程调度context、java 项目开发中中如何解决高并发问题、多线程并发会造成程序周期性崩溃吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)