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. 纯CSS3浮雕质感的立体文字旋转动画

    还记得之前分享过一个CSS3 文字3D翻转特效,这个效果让文字有一种立体的视觉效果.今天要分享的这款CSS3文字动画特效更加炫酷,它不仅有立体的3D效果,而且文字整体展现出一种浮雕质感的视觉效果,并且 ...

  2. 【Unity】项目工程源码

    Unity开发者俱乐部 http://blog.csdn.net/dingxiaowei2013/article/details/50605208 游戏蛮牛 9秒社团 6m5m raywenderli ...

  3. java 中 ResourceBundle 使用 国际化使用

    java 中 ResourceBundle 使用 可以根据以下类进行获取国际化文件: package org.mybatis.generator.internal.util.messages; imp ...

  4. Linux下用gSOAP开发Web Service服务端和客户端程序

    网上本有一篇流传甚广的C版本的,我参考来实现,发现有不少问题,现在根据自己的开发经验将其修改,使用无误:另外,补充同样功能的C++版本,我想这个应该更有用,因为能用C++,当然好过受限于C. 1.gS ...

  5. FFMPEG 入门

    1. 下载网站:https://ffmpeg.zeranoe.com/builds/ 先后下载 Win32 Shared 和 Win32 Dev 两个版本,分别解压缩. 2. 用Visual Stud ...

  6. 一个自定义python分布式专用爬虫框架。支持断点爬取和确保消息100%不丢失,哪怕是在爬取进行中随意关停和随意对电脑断电。

    0.此框架只能用于爬虫,由框架来调度url请求,必须按照此方式开发,没有做到类似celery的通用分布式功能,也不方便测试.可以使用另外一个,基于函数式编程的,调度一切函数的分布式框架,做到了兼容任何 ...

  7. python把文件从一个目录复制到另外一个目录,并且备份

    #!/usr/bin/python # -*- coding: utf-8 -*- import os,sys,md5,datetime,shutil,time,zipfile,chardet # c ...

  8. Tensorflow一些常用基本概念与函数

    1.tensorflow的基本运作 为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始: import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf. ...

  9. C++学习 —— 灵活的继承特性

    0.继承与算法开发 在之前的笔记中,我展示了来自继承的威力.继承这种机制能够大幅度减小编码量,子类可以继承父类所有的变量,方法.利用这种机制,我们可以在其他人工作的基础上,完成有自己特色的部分.比如我 ...

  10. Go 用JSON加载表格数据

    支持热重载reload,但会有一些问题,下面注释有写 package table import ( "runtime/debug" ) //IntArray int类型数组 typ ...