GO基础进阶篇 (七)、并发与并行

并发与并行

  1. 并发 (Concurrency):

    • 定义: 并发是指在同一时间段内处理多个任务,但不一定是同时执行。在并发中,任务之间可能是交替执行的,通过时间片轮转的方式实现。
    • 场景: 并发通常用于提高系统的响应性,使程序能够在多个任务之间切换,避免某个任务阻塞导致整个系统停滞。
    • 模型: 在并发中,通常使用线程、进程或者协程来执行不同的任务。在单核处理器上,通过时间片轮转实现并发;在多核处理器上,不同的任务可以并行执行。
  2. 并行 (Parallelism):

    • 定义: 并行是指在同一时刻执行多个任务,即多个任务同时进行。在并行中,每个任务都有自己的处理单元,可以独立运行,而不受其他任务的影响。
    • 场景: 并行通常用于利用多核处理器,加速计算过程,提高系统性能。并行性是一种更直接的同时执行多个任务的方式。
    • 模型: 在并行中,通常使用多个处理器核心来执行不同的任务。每个处理器核心可以独立执行指令,因此多个任务可以同时进行。
      在这里插入图片描述

进程、线程与协程

在 Go 语言中,有三个主要的并发模型:进程、线程和协程。Go 语言通过 goroutine 和 channel 提供了方便且高效的并发编程工具。

1. 进程(Processes):

  • 定义:进程是独立运行的程序实例,每个进程都有自己的内存空间和系统资源,相互之间通常是隔离的。
  • Go 中的表示:Go 语言本身不直接提供对进程的支持,而是依赖于操作系统的进程管理机制。你可以使用 os/exec 包来创建和执行外部进程。

2. 线程(Threads):

  • 定义:线程是操作系统调度的最小执行单位,多个线程可以在同一进程内共享相同的内存空间,但每个线程有自己的寄存器和栈。
  • Go 中的表示:Go 语言的运行时调度器会在逻辑处理器上调度 goroutines。每个 goroutine 在一个线程上运行,但是 goroutines 的调度和管理是由 Go 的运行时系统完成的。

3. 协程(Goroutines):

  • 定义:协程是 Go 语言中的轻量级线程,由 Go 的运行时系统调度。协程是独立于线程的执行单位,它们由 Go 语言的运行时系统自行管理。
  • 特点:相比于传统线程,协程的创建和销毁成本很低,因此可以轻松创建大量的协程。协程之间通过通道(channel)进行通信,这是 Go 语言并发模型的关键部分。
  • 创建和使用:使用 go 关键字可以创建一个新的 goroutine。例如:go func() { /* 代码 */ }()

以下是一个简单的例子,演示如何使用协程和通道实现并发编程:

package main

import (
	"fmt"
)

func main() {
   
	go printNumbers()
	for i := 0; i < 100; i++ {
   
		fmt.Println("main", i)
	}
}
func printNumbers() {
   
	for i := 0; i < 100; i++ {
   
		fmt.Println("函數內部", i)
	}
}

上面的例子中,两处fmt将以并发的形式交替执行。

Goroutine的规则:

  • 当新的Goroutine开始时,Goroutine调用立即返回。与函数不同,go不等待Goroutine执行结束
  • 当Goroutine调用,并且Goroutine的任何返回值被忽略后,go立即执行到下一行代码
  • 当main的进程终止后,程序将被终止,其他正在执行的Goroutine将不会运行。上面的例子中,main进程的循环条件改为 i < 1,则有可能子携程还未开启,程序就结束了
主Goroutine

封装main函数的Goroutine称为主Goroutine。
主Goroutine所做的工作并非执行main函数那么简单。它首先要做的是:设定每一个Goroutine所能申请到的栈空间的最大尺寸。在32位的计算机中,最大尺寸为250M。在64位计算机中,最大尺寸为1GB。如果某个Goroutine使用的栈空间超出最大尺寸。系统会产生栈溢出(stack overflow)的恐慌。程序也将终止。
最大尺寸设定完成后,将会进行一下步骤:

  • 创建一个defer,用于处理主Goroutine退出时的必要操作,因为主Goroutine可能会异常结束。
  • 启用专用于在后台清扫内存垃圾的Goroutine,并设置GC可用的标记。
  • 执行main包应用包下的所有init函数。
  • 执行main函数
  • 结束主Goroutine

相关推荐

  1. GO基础 (八)、runtime包

    2023-12-29 15:22:04       45 阅读
  2. GO基础 (六)、I/O流

    2023-12-29 15:22:04       33 阅读
  3. GO基础 (十二)、反射

    2023-12-29 15:22:04       36 阅读
  4. GO基础 (十三)、泛型

    2023-12-29 15:22:04       32 阅读
  5. go语言——接口

    2023-12-29 15:22:04       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-29 15:22:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-29 15:22:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-29 15:22:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-29 15:22:04       20 阅读

热门阅读

  1. 我是如何学习 redis 的

    2023-12-29 15:22:04       30 阅读
  2. 路由的安装顺序

    2023-12-29 15:22:04       32 阅读
  3. CollectionUtils

    2023-12-29 15:22:04       28 阅读
  4. uniapp 相关知识点总结整理

    2023-12-29 15:22:04       28 阅读
  5. 渗透测试中常见的端口及其服务

    2023-12-29 15:22:04       31 阅读
  6. centos7安装zabbix-agent2

    2023-12-29 15:22:04       36 阅读
  7. 简略入门Python笔记

    2023-12-29 15:22:04       41 阅读