Go 语言入门很简单 -- 15. Go 并发基础知识 #私藏项目实操分享#

简介: Go 语言入门很简单 -- 15. Go 并发基础知识 #私藏项目实操分享#

在操作系统中,进程和线程的执行都具有并发性。

并发是指向一段时间内,多个任务可以共享系统资源,同时执行。

并行是指从某个时刻开始,多个任务同时执行。

image.png

程序的顺序执行

如果在程序中,语句一条语句一条语句顺序排列的,如果系统中只有一个程序,那么程序执行时也是按照程序语句排列先后次序,一条一条地执行下去。这种方式就像工厂生产流水线加工方式那样,这种程序设计方式就叫做顺序程序设计。

在单任务、单处理机系统环境中,内存中只有一道程序作业在执行,一个程序完成后,下一个程序作业才能进入内存继续执行。

这种顺序执行的程序有三个特点:

  • 严格顺序执行。每条程序语句的执行都以前一条语句的结束为前提条件
  • 一个程序在计算机中运行时独占全部系统资源。只有程序本身的动作才能改变程序的运行环境。
  • 程序的执行结果与程序的运行速度无关。即处理机在执行程序任何两条语句之间的停顿,对程序的运算结果不发生影响。

这三个特点概括起来就是程序的封闭性可再现性

封闭性:程序一旦运行起来,其计算结果仅仅取决于程序本身,即运行结果唯一。

可再现性:指同一程序可反复执行,且每次执行结果相同。

程序的并发执行

程序的顺序执行限制系统内存中只有一道程序作业,这显然限制了系统性能的发挥,且资源利用率不高。

现代操作系统都支持程序的并发执行。

所谓并发执行是指在同一时间间隔内,多个程序可以“同时”执行。

在单处理机系统中,进程(或线程)通过时间片或者让出控制权来实现任务切换,以达到“同时”运行多个程序的目的。

这种方式叫做程序并发执行,但实际上任何时刻都只有一个任务被执行,其他任务则通过某个算法来排队准备执行。

即宏观上多个程序任务是“同时”执行,但微观上各任务还是一个一个地顺序执行。

程序的并发执行可以使得多个程序可以共享系统资源,提高系统资源利用率,还可以增加系统吞吐量。

同时,系统的并发执行和资源共享也使得系统环境变得非常复杂,不像顺序执行那么简单。

程序的并发执行基本是由操作系统提供的,Go 在语言层面就支持并发特性。

程序的并行执行

和并发执行不同,程序的并行执行是指同一时刻,多个程序可以同时执行。在多处理机系统中,可以让多个进程,或同一进程内的多个线程做到真正意义上的同时执行,它们之间不需要排队(这是在理想情况下,系统中进程(线程)的数量可能超过处理机的数量,这是依然需要排队)。在这种情况下,多个程序才能达到真正意义上的“同时”执行,即并行执行。

进程的概念

进程是在并发环境下,程序的一次动态执行过程。它由进程控制块(PCB)、程序和数据三部分组成,进程在它的生命周期内可能处于执行、就绪、阻塞三种基本状态。

在多任务操作系统中,多个进程可以并发执行,而且进程是系统资源分配的基本单位。系统中每个进程都有自己的内存映像区,且互不影响,所以管理简单,但缺点是系统开销大。所以,系统能同时创建的进程数量是有限的,不能太多。

线程的概念

由于进程的系统开销大,操作系统的设计者们又提出来更小的独立运行的单位——线程。

通过线程来提高系统内程序并发执行的程度,从而进一步提高系统的吞吐量。

在操作系统中,线程是由进程创建的,所以它继承了进程的部分资源,且具有进程的一些基本特征。所以多个线程之间也可以并发执行,且比进程的系统开销小。

但是,和进程一样,线程依然是由系统内核管理的,所以在高并发情况下,系统能创建的线程数量依然有限,效率也不高。

协程的概念

协程本质上是一种用户态线程,不需要操作系统进行抢占式调度,而且在真正的实现中寄存于线程中。因此,协程系统开销极小,可以有效提高线程任务的并发性,避免高并发模式下线程的缺点。

协程最大优势在于其“轻量级”,可以轻松创建上百万个而不会导致系统资源衰竭,而系统最多能创建的进程、线程的数量却少得多。

使用协程的有点是编程简单,结果清晰。但缺点是需要语言的支持,如果语言不支持,则需要用户在程序中自行实现调度。

目前,原生支持协程的语言还很少。

Goroutine

Go 语言在语言级别支持轻量级线程,叫做 Goroutine,Go 语言标准库提供的所有系统调用操作(包括同步I/O操作),都会让出处理机给其他 Goroutine。这使得轻量级线程的切换管理不依赖于系统的进程和线程,也不依赖于 CPU 的核心数量。

相关文章
|
1天前
|
人工智能 Go 调度
掌握Go并发:Go语言并发编程深度解析
掌握Go并发:Go语言并发编程深度解析
|
1天前
|
SQL 关系型数据库 MySQL
Golang数据库编程详解 | 深入浅出Go语言原生数据库编程
Golang数据库编程详解 | 深入浅出Go语言原生数据库编程
|
2天前
|
Go 开发者
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
【4月更文挑战第21天】本文介绍了Go语言中的流程控制语句,包括`if`、`switch`和`for`循环。`if`语句支持简洁的语法和初始化语句,但需注意比较运算符的使用。`switch`语句提供多分支匹配,可省略`break`,同时支持不带表达式的形式。`for`循环有多种形式,如基本循环和`for-range`遍历,遍历时修改原集合可能导致未定义行为。理解并避免易错点能提高代码质量和稳定性。通过实践代码示例,可以更好地掌握Go语言的流程控制。
11 3
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
|
2天前
|
Go
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
【4月更文挑战第21天】Go语言函数是代码组织的基本单元,用于封装可重用逻辑。本文介绍了函数定义(包括基本形式、命名、参数列表和多返回值)、调用以及匿名函数与闭包。在函数定义时,注意参数命名和注释,避免参数顺序混淆。在调用时,要检查并处理多返回值中的错误。理解闭包原理,小心处理外部变量引用,以提升代码质量和可维护性。通过实践和示例,能更好地掌握Go语言函数。
16 1
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
|
3天前
|
程序员 Go API
【Go语言快速上手(二)】 分支与循环&函数讲解
【Go语言快速上手(二)】 分支与循环&函数讲解
|
3天前
|
Go
Golang深入浅出之-Go语言基础语法:变量声明与赋值
【4月更文挑战第20天】本文介绍了Go语言中变量声明与赋值的基础知识,包括使用`var`关键字和简短声明`:=`的方式,以及多变量声明与赋值。强调了变量作用域、遮蔽、初始化与零值的重要性,并提醒读者注意类型推断时的一致性。了解这些概念有助于避免常见错误,提高编程技能和面试表现。
18 0
|
3天前
|
编译器 Go 开发者
Go语言入门|包、关键字和标识符
Go语言入门|包、关键字和标识符
22 0
|
17天前
|
Go
go语言中的数据类型
go语言中的数据类型
13 0
|
23天前
|
Go 开发者
掌握Go语言:Go语言结构体,精准封装数据,高效管理实体对象(22)
掌握Go语言:Go语言结构体,精准封装数据,高效管理实体对象(22)
|
23天前
|
安全 Go
掌握Go语言:Go语言通道,并发编程的利器与应用实例(20)
掌握Go语言:Go语言通道,并发编程的利器与应用实例(20)