go的奇怪问题,多线程死循环不占CPU。
这一段怎么看都时死循环的代码,居然不占CPU,说明go内部给锁住了。 但是把 ks := make([]int, 100000) 改成 ks := make([]int, 1000) 就可以跑满CPU了。 我用的是 1.6版, 1.5版的这种问题更严重...阅读全文
这一段怎么看都时死循环的代码,居然不占CPU,说明go内部给锁住了。 但是把 ks := make([]int, 100000) 改成 ks := make([]int, 1000) 就可以跑满CPU了。 我用的是 1.6版, 1.5版的这种问题更严重...阅读全文
所有涉及到存储的地方都是极易出现“坑”的地方,Kubernetes也不例外。 一、问题起因 问题始于昨天升级一个stateful service的操作。该service下的Pod挂载了使用ceph RBD提供的一个Persistent Volume。该Pod是用普通deployment部署的,并没有使用处于alpha状态的PetSet。改动仅仅是image的版本发生了变化。我执行的操作如下: # kubectl apply -f index-api.yaml 操作是成功的。但命令执行后,再次查看index-api这个Pod的状态,该Pod的状态长期处于:“ContainerCreating”,显然Pod没能重启成功。 进一步通过describe pod 检视events,发现如下Warnin...阅读全文
文链接: https://lihaoquan.me/2016/11/4/about-filelock.html 有时候,我们使用go语言开发一些程序的时候,往往出现多个进程同时操作同一份文件的情况,这很容易导致文件中的数据混乱。 我们需要采用一些手段来平衡这些冲突:需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock。 对于flock,我们最常见的例子就是nginx,进程起来后就会把当前的PID写入这个文件,当然如果这个文件已经存在了,也就是前一个进程还没有退出,那么Nginx就不会重新启动。 flock 是对于整个文件的建议性锁。也就是说,如果一个进程在一个文件(inode)上放了锁,那么其它进程是可以知道的。(建议性锁不强求进程遵守。) 最棒的一点是,它的第...阅读全文
sync.Once可以实现单例模式,确保sync.Once.Do(f func())只会被执行一次,可以初始化某个实例单例。 针对Golang 1.9的sync.Once,与Golang 1.10一样。 源代码位置:sync\once.go。 结构体 Once结构体定义如下: type Once struct { m Mutex done uint32 // 初始值为0表示还未执行过,1表示已经执行过 } Do func (o *Once) Do(f func()) { // done==1表示已经执行过了,直接结束返回 if atomic.LoadUint32(&o.done) == 1 { return } // 锁住对象,避免并发问题 o.m.Lock() defer o.m.Unlo...阅读全文
最近写项目,需要用到信号量等待一些资源完成,但是最多等待N毫秒。 在C语言里,有如下的API来实现带超时的信号量等待: C 12345 SYNOPSIS #include
一:原子操作CAS(compare-and-swap) 原子操作分三步:读取addr的值,和old进行比较,如果相等,则将new赋值给*addr,他能保证这三步一起执行完成,叫原子操作也就是说它不能再分了,当有一个CPU在访问这块内容addr时,其他CPU就不能访问 func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool) TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25 MOVD addr+0(FP), R3 MOVD old+8(FP), R4 MOVD new+16(FP), R5 SYNC LDAR (R3), R6 CMP R6, R4 BNE 7(PC) STD...阅读全文
import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup wg.Add(3) s1 := 0 s2 := 0 go func() { defer wg.Done() js() }() go func() { defer wg.Done() s1 = a1(1, 2) }() go func() { defer wg.Done() //todo 在这里加睡眠时间,来测试执行结果 time.Sleep(10*time.Second) s2 = a2(11, 2) }() wg.Wait() fmt.Println("s1=", s1) fmt.Println("s2=", s2) //打印时间 fmt.Println(t...阅读全文
使用channel 协程间通讯的普通使用, 发送值给channel, 外部channel接收. func t1() { ch := make(chan int) go func() { ch <- 1 }() // <-ch // 导致下面语句阻塞 fmt.Println("channel int", <-ch) } 复制代码channel int 1 复制代码channel支持缓冲区 func t2() { ch := make(chan int, 3) go func() { ch <- 1 ch <- 2 ch <- 3 ch <- 4 // 会阻塞写不入, 除非ch已接收 close(ch) // 关闭后不能再写入, 并且缓冲区内为空时则返回零值 }() fmt.Println("b...阅读全文