golang其实也可以优先调度
线上一个服务有个严重问题,处理消息数1k/s提升不上去,经过查看是阻塞在了一个新加的函数上,这个函数负责收集信息,送到一个channel上,再由某个函数处理,这个处理函数很简单,看不出任何问题,最大的特点是为了不加锁,只起一个goroutine。
问题很明显了,只起一个goroutine,当系统繁忙和存在大量goroutine的时候,会得不到调度,无法处理收集到的数据,然后channel缓冲满,导致收集函数阻塞在发送数据到channel上,进而阻塞了消息处理。
该获得调度的没有被调度,不该获得调度的却获得调度了,而go runtime不可能知道那个goroutine应该被调度,只能是公平调度,但是公平调度却造成了堵塞!
这种问题其实很普遍,不是一个goroutine的问题!就算你开了多个goroutine,仍然可能得不到调度!(当然,是在繁忙的时候,大部分时候不存在这种问题)
当然,这个问题可以用全局队列来解决,不使用channel,也就不存在阻塞的问题,有些优秀的库就是这样提升吞吐的。但是仍然会有偶尔延迟的情况,因此最后还是要解决,调度的问题!
这篇文章《记一次latency问题排查:谈Go的公平调度的缺陷》也谈到go这个问题,并认为问题无解。
其实我们可以试试,golang提供的一个更简单的方法,runtime.LockOSThread()。
官方介绍:
LockOSThread wires the calling goroutine to its current operating system thread. Until the calling goroutine exits or calls UnlockOSThread, it will always execute in that thread, and no other goroutine can.
重点在于no other goroutine can,LockOSThread本来是设计给opengl等东西用的,但是从官方这个说明来看,我们可以利用它做优先调度,将某个goroutine锁定到某个系统线程,这个线程只调度这个goroutine,进而可以被优先调度(相对其他goroutine)。因为系统线程是根据时间片调度的,因此能让这个goroutine得到获得更多时间。
下面的test,显示了runtime.LockOSThread()的确能影响调度,注释掉runtime.LockOSThread(),有2-60倍的时间差。
package main import (
"fmt"
"os"
"runtime"
"time"
) func main() { var ch = make(chan bool, )
var begin = make(chan bool) go func() {
runtime.LockOSThread()
<-begin
fmt.Println("begin")
tm := time.Now()
for i := ; i < ; i++ {
<-ch
}
fmt.Println(time.Now().Sub(tm))
os.Exit()
}() for i := ; i < ; i++ {
// 负载
go func() {
var count int
load :=
for {
count++
if count >= load {
count =
runtime.Gosched()
}
}
}()
} for i := ; i < ; i++ {
go func() {
for {
ch <- true
}
}()
} fmt.Println("all start")
begin <- true select {}
}
golang其实也可以优先调度的更多相关文章
- golang channel的使用以及调度原理
golang channel的使用以及调度原理 为了并发的goroutines之间的通讯,golang使用了管道channel. 可以通过一个goroutines向channel发送数据,然后从另一个 ...
- [golang]Golang实现高并发的调度模型---MPG模式
Golang实现高并发的调度模型---MPG模式 传统的并发形式:多线程共享内存,这也是Java.C#或者C++等语言中的多线程开发的常规方法,其实golang语言也支持这种传统模式,另外一种是Go语 ...
- 利用python画出动态高优先权优先调度
之前写过一个文章. 利用python画出SJF调度图 动态高度优先权优先调度 动态优先权调度算法,以就绪队列中各个进程的优先权作为进程调度的依据.各个进程的优先权在创建进程时所赋予,随着进程的推进或其 ...
- Golang源码学习:调度逻辑(一)初始化
本文所使用的Golang为1.14,dlv为1.4.0. 源代码 package main import "fmt" func main() { fmt.Println(" ...
- Golang源码学习:调度逻辑(二)main goroutine的创建
接上一篇继续分析一下runtime.newproc方法. 函数签名 newproc函数的签名为 newproc(siz int32, fn *funcval) siz是传入的参数大小(不是个数):fn ...
- Golang源码学习:调度逻辑(四)系统调用
Linux系统调用 概念:系统调用为用户态进程提供了硬件的抽象接口.并且是用户空间访问内核的唯一手段,除异常和陷入外,它们是内核唯一的合法入口.保证系统的安全和稳定. 调用号:在Linux中,每个系统 ...
- Golang源码学习:调度逻辑(三)工作线程的执行流程与调度循环
本文内容主要分为三部分: main goroutine 的调度运行 非 main goroutine 的退出流程 工作线程的执行流程与调度循环. main goroutine 的调度运行 runtim ...
- golang中goroutine协程调度器设计策略
goroutine与线程 /* goroutine与线程1. 可增长的栈os线程一般都有固定的栈内存,通常为2MB,一个goroutine的在其声明周期开始时只有很小的栈(2KB),goroutine ...
- golang模拟动态高优先权优先调度算法
实验二 动态高优先权优先调度 实验内容 模拟实现动态高优先权优先(若数值越大优先权越高,每运行一个时间单位优先权-n,若数值越小优先权越高,没运行一个时间单位优先权+n),具体如下: 设置进程体:进 ...
随机推荐
- C(8)
C语言位运算与文件 本章引言: 在不知不觉中我们的C高速入门系列已经慢慢地接近尾声了,而在这一节中,我们会对 C语言中的位运算和文件进行解析,相信这两章对于一些人来说是陌生的,由于非常多 老师都会跳过 ...
- 【Jsp】JSP自己定义标签与MODEL1、MODEL2标准
在JSP2.0之后支持自己定义标签,如今一般都是jsp2.4的版本号了,所以无须考虑版本号的问题. 直接使用就能够了.尽管一般开发的过程中,非常少会自己定义JSP标签.可是通过一个JSP自己定义标签的 ...
- 为了提高性能,怎样动态载入JS文件
超级表格是一款多人协作的在线表格.程序相当复杂,用到十几个JS文件. 可是有些文件是在打开某些类型的表格时才须要载入. 比如,仅仅有当打开甘特图表格时,才须要载入gantetu.js文件. 那么问题来 ...
- redis 简单安装使用
官方站点:http://redis.io/ 官方下载:http://redis.io/download 能够依据须要下载不同版本号 windows版:https://github.com/mythz/ ...
- OC对象与Core Foundation对象的转换
OC对象使用了ARC,自己主动释放内存,可是CF中的对象没有ARC,必需要手动进行引用计数和内存释放. 两者对象之间的互相转换有三种形式: 1.__bridge: 直接转换,部改变对象的持有状况: i ...
- 初识ajax
ajax优势:不刷新整个页面,只刷新局部(无刷新) 无刷新的好处: 只更新部分页面,有效利用宽带 提供连续的用户体验 提供类似C/S的交互效果,操作更方面 什么是ajax AJAX :代表 Async ...
- 史上最强学生管理系统之IO版
既上一博发布的ArrayList版本之后,新一版的IO版又来了,其实只是在上一个版本里面添加了IO流的内容,将存入更改的信息更新到了文件中而已,这个版本网上仍然很多,本人只是在某些方面稍加修改,因为自 ...
- ligerUI---ligerForm中下拉框使用
写在前面: 最近项目的前框框架用的是ligerUI,一开始我是拒绝的,因为貌似ligerUI很少有人用,我真的很想问我们team的斌哥哥为什么要用ligerUI来做前端框架?????(啊哈哈哈,用什么 ...
- Spring拦截器总结
本文是对慕课网上"搞定SSM开发"路径的系列课程的总结,详细的项目文档和课程总结放在github上了.点击查看 Spring过滤器WebFilter可以配置中文过滤 拦截器实现步骤 ...
- 'boost/iterator/iterator_adaptor.hpp' file not found之xcode生成时报错的解决方案
xcode生成rn(0.49.3)项目的时候出现“'boost/iterator/iterator_adaptor.hpp' file not found之xcode”报错. 原因: /Users/x ...