笔记篇:工程实践| 青训营

并行与并发

  • 并发Concurrency)是指在单个处理器上同时执行多个任务的能力。它是通过在时间上交替执行任务,使得每个任务都有机会向前推进。在并发中,任务之间相互独立,每个任务按照自己的节奏执行,但它们之间会交替执行。使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的。
  • 并行Parallelism)指在同一时刻,有多条指令在多个处理器上同时执行。
  • 并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。
  • 并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在,并发是并行的假象,并行可以认为实现并发的手段

image.png

计算机的"大脑"。

  • 在计算机领域中,处理器和CPUCentral Processing Unit)通常可以互换使用。它们都指代计算机的中央处理器部件,负责执行指令和进行计算。
  • 处理器可以是单核或多核的,分别支持并发执行和并行处理。
  • 每个核心都是一个独立的处理单元,每个核心都包含算术逻辑单元(ALU)、寄存器、高速缓存等,它可以执行指令和进行数据处理。

进程、线程、协程

  1. 进程Process):进程是操作系统分配资源和管理程序执行的基本单位。进程之间是相互独立的,拥有独立的内存空间,可以同时运行多个进程,实现多任务操作。进程间通信需要使用额外的机制,如共享内存、管道等。

  2. 线程Thread):线程是进程中执行任务的最小单位。程共享进程的内存空间和上下文,可以同时执行多个线程,实现多线程并发操作。线程之间可以直接通信和共享数据。

  3. 协程Coroutine):协程是一种用户态的轻量级线程,它并不是由操作系统内核来管理和调度,而是由程序员控制其执行和切换的时机。可以在同一个线程内实现多个协程的切换,实现并发和并行操作。

image.png 5. **进程是程序执行的过程,包括了动态创建、调度和消亡的整个过程。 进程是一个正在运行的程序,而线程是进程中的一个执行单元。** 6. **一个核心可以同时处理一个进程或一个线程。** 7. 当一个核心处理一个进程时,它会在不同进程之间切换,每个进程获得一小段时间来执行。当一个核心处理一个线程时,它会在不同线程之间切换,以实现并发执行。 多核处理器可以同时处理多个进程和多个线程,以提高计算机的处理能力和并行处理能力。 8. 执行线程是在进程内部进行的,但**并不是一定需要一个进程存在**在一些嵌入式系统或特定的环境下,可以直接创建和执行线程,而不需要一个完整的进程。这种情况下,线程可以更轻量级地创建和销毁,因为它们不需要独立的进程资源。 然而,在大多数的操作系统和计算机系统中,线程是依附于进程的。也就是说,当一个进程创建时,至少会有一个线程存在,这个线程通常被称为主线程。进程创建后,可以动态地创建更多的线程,并在这些线程之间进行切换和执行。 image.png

Go并发

参考---Go 的并发

  • Go中的多线程编程称为goroutine,目前统一译为协程。因为协程kb级别,轻量很多,一次可以创建上万个协程,这也就是Go语言更适合高并发场景的原因。
  • go 的并发编程采用的 CSP (Communicating Sequential Process) 模型,主要基于协程 goroutine 和通道 channel
  • 在函数中调用了休眠(sleep)函数,这个函数就会告诉 Go 调度器去调度其他可被调度的 Go 协程。
    • 调度器Scheduler)是操作系统或者编程语言运行时系统的一部分,负责协调和管理多个任务或线程的执行顺序和分配计算资源。
    • Go语言中,调度器Goroutine Scheduler)是运行时系统的一部分,负责调度和管理Goroutine的执行。它使用了一种称为“抢占式的协作式调度(Preemptive Cooperative Scheduling)”的方式,即允许Goroutine主动让出执行权,也可以被强制抢占执行权,以确保公平性和避免资源竞争。- 只有非休眠(non-sleeping)的 Go 协程才会被认为是可被调度的。

Channel

  • src 是源代码(Source Code)的缩写,通常用于指代源代码文件或源代码目录。
  • go语言提供的消息通信机制称为channelgo语言在设计上强调不要通过共享内存来通信,而应该通过通信来共享内存,但实际都有存在呢。
  • Go语言中的channel有三种基本操作:发送、接收、关闭
  • 关闭一个channel之后,就不能再向它发送数据了,但是仍然可以从它接收数据。
  • 阻塞式机制:当一个协程向一个channel发送数据时,如果channel已经满了,发送操作会被阻塞,直到有其他协程从channel中取走了数据。同样地,当一个协程从一个channel中接收数据时,如果channel中没有数据可供接收,接收操作会被阻塞,直到有其他协程向channel中发送了数据。这种阻塞式的机制可以保证协程之间的同步和通信。
  • 容量 :无缓冲channel的容量为0,意味着它不能存储任何数据,数据发送者必须等待数据接收者接收数据后才能继续发送。有缓冲channel的容量大于0,可以存储一定数量的数据,只有当缓冲区满时,发送操作才会阻塞。
  • Go语言中,通过在函数或方法后面使用一对括号,可以直接调用该函数或方法。

import (
	"fmt" 
)

func printhello() {
	fmt.Println("hello world")
}

func main() { // 声明 main 主函数
	fmt.Println("Hello")
	go printhello()
	fmt.Println("world")
}

func CalSquare() {
	src := make(chan int)
	dest := make(chan int, 3)
	go func() {
	defer cLose(src )
	for i:=0;i<10;i++{
	src <- i
	}
	}()

	go func() {
	defer cLose(dest)
	for i := range src {
	dest <- i * i
	}
	}()

	for i := range dest {
	println(i)
	}
	

依赖管理

  • 依赖包和SDK类似,都是指向提供特定功能的软件工具或库。
  • 对于依赖包的管理经历了GOPATH,GO VENDOR, GO MODULE(由于对于sdk包版本的兼容控制)
image.png
  • 依赖分发proxy的模式---缓存的模式 具有相同思想,学下去。
全部评论

相关推荐

投递京东等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务