1. 为什么要有多线程
最早期的计算机十分原始,还没有操作系统。想要使用计算机时,人们先把计算机可以执行的指令刻在纸带上,然后让计算机从纸带上读取每一条指令,依次执行。这时候的计算机每次只能执行一个任务,是地地道道的单线程。
这种情况下就产生了三个问题:
-
计算资源的严重浪费
计算机在执行任务时,总少不了一些输入输出操作,比如计算结果的打印等。这时候CPU只能等待输入输出的完成。所以往往一个任务执行下来,可能CPU大部分人时间都是空闲的。
-
任务分配的不公平
现在假如我们有十个任务需要执行,这可是很常见的。而计算机每次只能执行一个任务,直到执行结束,中间不能中断。那么问题来了,应该如何分配?
-
程序编写十分困难
计算机一次只能执行一个任务,所以编写程序的时候往往要把很多工作集成到一个程序中,这给程序的编写人员带来了极大的挑战。能不能把程序分模块编写,然后让模块之间只进行必要的通信呢?
2. 什么是线程安全
线程安全是多线程编程是的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且准确的执行,不会出现数据污染等意外情况。上述是百度百科给出的一个概念解释。
换言之,线程安全就是某个函数在并发环境中调用时,能够处理好多个线程之间的共享变量,使程序能够正确执行完毕。也就是说我们想要确保在多线程访问的时候,我们的程序还能够按照我们的预期的行为去执行,那么就是线程安全了。
3. 线程不安全的原因
(1)一个或者多个操作在 CPU 执行的过程中被中断
(2)一个线程对共享变量的修改,另外一个线程不能立刻看到
(3)程序执行的顺序没有按照代码的先后顺序执行
4. Channel的线程安全
使用锁(lock)是确保线程安全的方式之一。
不同协程通过channel进行通信,本身的使用场景就是多线程,为了保证数据的一致性,Channel实现线程安全。
Channel的底层实现中,hchan结构体中采用Mutex锁来保证数据读写安全。
见网页:Go 语言入门指南——channel底层原理 | 青训营 - 掘金 (juejin.cn)
在对循环数组buf中的数据进行入队和出队操作时,必须先获取互斥锁,才能操作channel数据。
故Channel本身就是线程安全的。