golang 起超过100W的goroutine就会crash,这个算不算是个bug?


2036119xxxx
panic: inconsistent poll.fdMutex

goroutine 2041065 [running]:
internal/poll.(*fdMutex).rwlock(0xc420090050, 0xc517305500, 0x1089b36)
/usr/local/Cellar/go/1.10/libexec/src/internal/poll/fd_mutex.go:145 +0x13f
internal/poll.(*FD).writeLock(0xc420090050, 0x1, 0x10c1cee)
/usr/local/Cellar/go/1.10/libexec/src/internal/poll/fd_mutex.go:237 +0x32
internal/poll.(*FD).Write(0xc420090050, 0xc518138ee0, 0x7, 0x8, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.10/libexec/src/internal/poll/fd_unix.go:243 +0x46
os.(*File).write(0xc42000c018, 0xc518138ee0, 0x7, 0x8, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.10/libexec/src/os/file_unix.go:243 +0x4e
os.(*File).Write(0xc42000c018, 0xc518138ee0, 0x7, 0x8, 0x8, 0xc517a3bd50, 0x0)
/usr/local/Cellar/go/1.10/libexec/src/os/file.go:144 +0x6f
fmt.Fprint(0x10d2720, 0xc42000c018, 0xc5173057b8, 0x1, 0x1, 0x109ed40, 0x0, 0xc518138ed8)
/usr/local/Cellar/go/1.10/libexec/src/fmt/print.go:223 +0x8b
fmt.Print(0xc5173057b8, 0x1, 0x1, 0xc518138ed8, 0x0, 0x0)
/usr/local/Cellar/go/1.10/libexec/src/fmt/print.go:232 +0x57
main.test(0x1f24c1)
/Users/guanshuai/go/src/main.go:11 +0x81
created by main.main
/Users/guanshuai/go/src/main.go:19 +0x87
exit status 2

real 0m10.859s
user 0m29.635s
sys 0m10.859s
[guanshuai] src $


mac os

goroutine 15192446 [running]:
internal/poll.(*fdMutex).rwlock(0xc420080050, 0x1000000010bf000, 0x0)
/usr/local/go/src/internal/poll/fd_mutex.go:145 +0x13f
internal/poll.(*FD).writeLock(0xc420080050, 0xc420034800, 0xc4ddd4cc40)
/usr/local/go/src/internal/poll/fd_mutex.go:237 +0x32
internal/poll.(*FD).Write(0xc420080050, 0xc4ddcea480, 0x11, 0x20, 0x0, 0x0, 0x0)
/usr/local/go/src/internal/poll/fd_unix.go:243 +0x46
os.(*File).write(0xc42000c018, 0xc4ddcea480, 0x11, 0x20, 0x10, 0x10, 0x11)
/usr/local/go/src/os/file_unix.go:243 +0x4e
os.(*File).Write(0xc42000c018, 0xc4ddcea480, 0x11, 0x20, 0x8, 0xc4531795a0, 0x0)
/usr/local/go/src/os/file.go:144 +0x6f
fmt.Fprintln(0x10d09a0, 0xc42000c018, 0xc4ddd7e7a8, 0x2, 0x2, 0x109d300, 0x0, 0xc4531795a0)
/usr/local/go/src/fmt/print.go:255 +0x8b
fmt.Println(0xc4ddd7e7a8, 0x2, 0x2, 0xc4531795a0, 0x0, 0x0)
/usr/local/go/src/fmt/print.go:264 +0x57

  

// lock adds a reference to mu and locks mu.
// It reports whether mu is available for reading or writing.
func (mu *fdMutex) rwlock(read bool) bool {
var mutexBit, mutexWait, mutexMask uint64
var mutexSema *uint32
if read {
mutexBit = mutexRLock
mutexWait = mutexRWait
mutexMask = mutexRMask
mutexSema = &mu.rsema
} else {
mutexBit = mutexWLock
mutexWait = mutexWWait
mutexMask = mutexWMask
mutexSema = &mu.wsema
}
for {
old := atomic.LoadUint64(&mu.state)
if old&mutexClosed != 0 {
return false
}
var new uint64
if old&mutexBit == 0 {
// Lock is free, acquire it.
new = (old | mutexBit) + mutexRef
if new&mutexRefMask == 0 {
panic("inconsistent poll.fdMutex")
}
} else {
// Wait for lock.
new = old + mutexWait
if new&mutexMask == 0 {
panic("inconsistent poll.fdMutex")
}
}
if atomic.CompareAndSwapUint64(&mu.state, old, new) {
if old&mutexBit == 0 {
return true
}
runtime_Semacquire(mutexSema)
// The signaller has subtracted mutexWait.
}
}
}

  

// 1 bit - lock for write operations.
// 20 bits - total number of references (read+write+misc).
// 20 bits - number of outstanding read waiters.
// 20 bits - number of outstanding write waiter

// fdMutex.state is organized as follows:
// 1 bit - whether FD is closed, if set all subsequent lock operations will fail.
// 1 bit - lock for read operations.
// 1 bit - lock for write operations.
// 20 bits - total number of references (read+write+misc).
// 20 bits - number of outstanding read waiters.
// 20 bits - number of outstanding write waiters.
const (
mutexClosed = 1 << 0
mutexRLock = 1 << 1
mutexWLock = 1 << 2
mutexRef = 1 << 3
mutexRefMask = (1<<20 - 1) << 3
mutexRWait = 1 << 23
mutexRMask = (1<<20 - 1) << 23
mutexWWait = 1 << 43
mutexWMask = (1<<20 - 1) << 43
)

互斥的变量里面是64位的数值

1.bit 代表是否关闭

2bit 锁的类型是读

3bit 锁的类型是写

4bit 可以递增的单位数值

5bit-- (22位)   掩码   2**22 = 2 * 2 ** 20

>>> import math
>>> pow(2, 20)
1048576
>>>

  在一个file 或者socket上最大的锁为1000000, 所以有人提交patch,提示更精细的panic

https://go-review.googlesource.com/c/go/+/119956

internal/poll: better panic message for lock overflow

const overflowMsg = "too many concurrent operations on a single file or socket (max 1000000)"

  

golang schedule crash的更多相关文章

  1. Go语言(golang)开源项目大全

    转http://www.open-open.com/lib/view/open1396063913278.html内容目录Astronomy构建工具缓存云计算命令行选项解析器命令行工具压缩配置文件解析 ...

  2. [转]Go语言(golang)开源项目大全

    内容目录 Astronomy 构建工具 缓存 云计算 命令行选项解析器 命令行工具 压缩 配置文件解析器 控制台用户界面 加密 数据处理 数据结构 数据库和存储 开发工具 分布式/网格计算 文档 编辑 ...

  3. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

  4. 面试必问:Golang高阶-Golang协程实现原理

    引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发) 进程和线程的区别 进程是计 ...

  5. Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践

    目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ?   RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...

  6. 【GoLang】GoLang 的流程与函数

    003.GO流程与函数 1 概述 1.1 Go中流程控制分三大类:条件判断,循环控制和无条件跳转 2 流程 2.1 if 2.1.1 if条件判断语句中不需要括号 2.1.2 条件判断语句里面允许声明 ...

  7. Golang网络库中socket阻塞调度源码剖析

    本文分析了Golang的socket文件描述符和goroutine阻塞调度的原理.代码中大部分是Go代码,小部分是汇编代码.完整理解本文需要Go语言知识,并且用Golang写过网络程序.更重要的是,需 ...

  8. Golang源码探索(二) 协程的实现原理

    Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻 ...

  9. Golang源码探索(三) GC的实现原理

    Golang从1.5开始引入了三色GC, 经过多次改进, 当前的1.9版本的GC停顿时间已经可以做到极短. 停顿时间的减少意味着"最大响应时间"的缩短, 这也让go更适合编写网络服 ...

随机推荐

  1. Windows上SSH服务器的配置以及客户端的连接

    1.      ssh简介以及本例的应用场景 ①       ssh的简介 SSH是一个用来替代TELNET.FTP以及R命令的工具包,主要是想解决口令在网上明文传输的问题.为了系统安全和用户自身的权 ...

  2. 第四百一十五节,python常用排序算法学习

    第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...

  3. ABBYY PDF Transformer+ 给你好看

    ABBYY PDF Transformer+是一个新的.全面的巧妙解决PDF文档的工具,它将泰比的光学字符识别(OCR)技术和Adobe®PDF技术完美结合,以确保实现便捷地处理任何类型的PDF文件, ...

  4. jmeter3.0下载及安装

    http://blog.csdn.net/shizhiailian/article/details/52443169 下载: https://archive.apache.org/dist/jmete ...

  5. CentOS安装和配置Nginx

    1. 首先Nginx官网找到最新的稳定版本,网站地址:http://nginx.org/en/linux_packages.html#stable 在/etc/yum.repos.d 下面创建一个文件 ...

  6. mysql主从复制-方案2

    MySQL主从介绍 (两台机器数据同步) 主:-->binlog 从:-->relaylog 主上有一个log dump线程,用来和从的I/O线程传递binlog 从上有两个线程,其中I/ ...

  7. [ICPC 北京 2017 J题]HihoCoder 1636 Pangu and Stones

    #1636 : Pangu and Stones 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In Chinese mythology, Pangu is the fi ...

  8. linux下批量杀死进程

    ps aux|grep python|grep -v grep|cut -c 9-15|xargs kill -15 管道符“|”用来隔开两个命令,管道符左边命令的输出会作为管道符右边命令的输入.下面 ...

  9. nw.js---创建一个hello word的方法

    一.如果用nw.js 来开发桌面应用 首先到Nw.js中文网下载软件: https://nwjs.org.cn/download.html 下载下来进行解压就可以了,绿色的免安装的,整个目录结果是这样 ...

  10. Nest.js 管道

    Docs: https://docs.nestjs.com/pipes 管道将输入数据转换为所需的输出.此外,它可以处理验证,当数据不正确时可能会抛出异常. 内置的 pipe import { Arg ...