常见的并发问题

Race Conditions

出现这种情况的问题原因大部分在于程序员思考问题都是顺序的

1 var data int
2 go func() { 1
3     data++
4 }()
5 if data == 0 {
6     fmt.Printf("the value is %v.\n", data)
7 }

如上图中第2行启动了一个新的goroutine,不能保证这个goroutine一定会在第5行之前执行。除非使用任何同步手段来限制执行顺序,否则这类RC问题一定会发生的

Atomicity

当某些东西具备Atomicity原子性时,我们说它运行在自己的上下文中,并且不可中断或者分割的。

提到上下文,我们要明确的上下文针对的范围,比如线程级、进程级、内核级、机器级,极大可能对应上下文的原子性无法在其他上下文保证,这就要求我们在谈及原子性时一定要明确原子性所指代的上下文

Memory Access Synchronization

如上边程序所示,data的访问并没有做任何同步限制,导致可能会在一些特殊情况下被修改,我们可以通过加锁的形式限制某些共享变量的访问,但是加锁会降低我们程序的性能,会使我们的程序中断

Deadlocks, Livelocks, and Starvation

死锁是所有并发的程序代码在等待彼此,在此情况下,如果没有外部介入程序永远不会恢复。死锁的4个必要条件:资源互斥、不可剥夺、循环等待、请求资源并保持