标签: 并发 清除筛选
    检查Golang程序中的数据竞争
    检查Golang程序中的数据竞争

    数据竞争是并发程序中最常见的,也是最难发现的并发问题,所幸的是,Go内置了在一定程度上可以发现竞争问题。你可以在测试数据竞争检测器(data race detector),或者运行程序时使用-race开启数据竞争检测器,或者在编译程序时开启,编译好的二进制程序在运行时也可以开启数据竞争检测:

    go test -race mypkg	// 测试mypkg包
    go run -race mysr
    
    Golang锁-Mutex的用法
    Golang锁-Mutex的用法

    因为并发编程中有竞争条件和数据竞争的问题,我们才需要将代码片段设定为临界区,通过使用Mutex等同步原语将临界区保护起来。接下来,我们来熟悉Go标准库的Mutex 的使用方法,看看它是如何保护临界区,解决竞争条件和数据竞争的问题的。

    一个并发问题

    有时候,我们很清楚地知道临界区或者共享资源,能主动地发现数据竞争问题;但是有时候,数据竞争问题却不那么容易被发现,比如下面这段代码,你认为有数据竞争

    竞争条件与数据竞争
    竞争条件与数据竞争

    竞争条件和数据竞争是两个相关的概念,它们都涉及多线程环境中的数据竞争。但是,它们也有如下一些重要的区别。

    • 竞争条件:指的是在多线程环境中,由于操作顺序的不确定性导致的程序执行结果的不确定性。例如,如果两个线程同时对同一个变量进行读/写操作,那么它们的执行顺序将会对最终的结果产生影响。这就是竞争条件。外部时序或排序的非确定性会产生竞争条件;典型的示例包括上下文切换、操作系统信号、多处理器上的内存操作和硬件中断等。竞争
    Go并发并不一定最快
    Go并发并不一定最快

    一般来说,正如我们平常理解的那样,将串行程序修改为并行程序之后,其性能会得到提升。但也不是绝对的,在某些情况下,串行编程性能反而更好。

    下面这个例子是快速排序的串行实现。

    // 快速排序中的分区,把a分成左右两部分,左边部分小于右边部分
    func partition(a []int, lo, hi int) int {
    	pivot := a[hi] // 将最后一个值作为分界值
    	i := l
    
    1/6/2026golang并发
    阿姆达尔定律:并发编程优化是有上限的
    阿姆达尔定律:并发编程优化是有上限的

    阿姆达尔定律(Amdahl's Law,Amdahl's Argument),计算机科学界的一个经验法则,因IBM公司计算机架构师吉恩·阿姆达尔而得名。阿姆达尔曾致力于并行处理系统的研究,他进行了一项富有洞察力的观察:提升系统的一部分性能对整个系统的性能有多大影响。这一观察被称为阿姆达尔定律:

    当提升系统的一部分性能时,对整个系统性能的影响取决于:

    • 这一部分有多重要。
    • 这一部分性能提升了多少。

    1/5/2026并发
    并发vs并行
    并发vs并行

    并发是同时处理很多事情,并行是同时做很多事情。

    并发是同时处理很多事情,有时间段的概念,这些事情可能会有一个先后顺序,但是会在这个时间段内去做。从这个时间段来看,这些事情都被处理了。

    比如我在编写代码的同时还在听着音乐,这两件事情如果被调度在同一个CPU上,它们是并发执行的。

    并行是在同一个时间点有多件事情都在做。如果手头阔绰,我还可以买一台机器放在旁边,打开Markdown编辑器编写文章的内容,同时音乐播放器在播放抖音上最流行的歌曲。这两台服务器可以并行地执行,在同一个时刻,两台服务器都在做着事情,这是并行。

    并发和并行并不相同,但是相关。如图,左边并发,右边并行。 ![并发vs并行

    1/3/2026并发并行
    适合并发编程的语言Golang
    适合并发编程的语言Golang

    当今很多高级编程语言都支持并发编程,但是Go语言绝对是很特殊的那一个,一开始它就从语言设计上为并发编程提供了最简单的方式,并且设计了对线程更轻量级的goroutine,还为CSP模型提供了容易使用的channel类型,并将其作为内建类型直接提供。

    2019年,在Go Time对Rob Pike和Robert Griesemer的访谈节目中,Rob Pike 谈到发明Go语言的想法时说道,“我们听到了一个C++新版本发

    1/2/2026golang并发