Go语言入门12(协程 goroutine)

这篇具有很好参考价值的文章主要介绍了Go语言入门12(协程 goroutine)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

协程

进程和线程

进程

​ 当运行一个应用程序的时候,操作系统会为这个应用程序启动一个进程。可以将这个进程看作一个包含了应用程序在运行中需要用到和维护的各种资源的容器。这些资源包括但不限于内存地址空间、文件和设备的句柄以及线程

线程

​ 一个线程是一个执行空间,这个空间会被操作系统调度来运行函数中所写的代码。每个进程至少包含一个线程,每个进程的初始线程被称作主线程。因为执行这个线程的空间是应用程序的本身的空间,所以当主线程终止时,应用程序也会终止。操作系统将线程调度到某个处理器上运行,这个处理器并不一定是进程所在的处理器

并发和并行

并发

​ 并发是指在一个逻辑处理器同时管理很多事情,这些事情可能只做了一半就被暂停去做别的事情了,golang的并发通过切换多个线程打到减少物理处理器空闲等待的目的

并行

​ 并行是让不同的代码片段同时在不同的物理处理器上执行,大多数情况下,并发的效果比并行好,因为操作系统的硬件的总资源一般很少,但能支持系统同时做很多事情

goroutine协程

在一个协程中运行函数

​ 在一个协程中运行一个函数其实很简单,只要在函数调用前加上go即可

// 随便写一个demo函数
func Demo01(num int, contain string) {
	for i := 0; i < num; i++ {
		fmt.Println("这是一个goroutine", contain)
	}
}
// 在协程中运行此函数
func main() {
    go Demo01(10,"调用Demo函数")
	fmt.Println("over!")
}
//输出:
//   over!

​ 上述代码由于demo调用在协程中进行,所以并不影响主函数的运行,当主函数运行结束之后,代码运行直接停止,所以协程并没有输出任何内容,因此我们可以使用sleep方法让主函数进入等待状态

// 随便写一个demo函数
func Demo01(num int, contain string) {
	for i := 0; i < num; i++ {
		fmt.Println("这是一个goroutine", contain)
	}
}
// 在协程中运行此函数
func main() {
    go Demo01(10,"调用Demo函数")
    time.Sleep(1000000000)
	fmt.Println("over!")
}
//输出:
//   这是一个goroutine demo调用
//   这是一个goroutine demo调用
//   这是一个goroutine demo调用
//   这是一个goroutine demo调用
//   这是一个goroutine demo调用
//   over!

​ 但是这样子让主函数等待协程运行,听起来是个蛮蠢的想法,我们可以使用一个另一种方式解决问题,Waitgroup方法

waitgroup方法

​ 我们可以在使用waitgroup方法先实例化一个计数器,wg,在协程中使用wg.done进行操作计数器,从而达到主函数等待协程运行的一个目的

// demo方法
// 同时因为我们要对wg进行操作,因此要把wg的指针传递给函数
func Demo01(num int, contain string, wg *sync.WaitGroup) {
    // 因为wg,done一般来说都在函数最后使用,因此我们把他放在defer延迟处理函数里面
	defer wg.Done()
	for i := 0; i < num; i++ {
		fmt.Println("这是一个goroutine", contain)
		time.Sleep(1000000000)
	}
}

// main方法
func main() {
    // 实例化计数器wg
	var wg sync.WaitGroup
    // 要运行两个goroutine函数
	wg.Add(2)
	go functions.Demo01(2, "the first goroutine!", &wg)
	go functions.Demo01(3, "the second goroutine!", &wg)
    // 等待两个goroutine运行完毕
	wg.Wait()
    // 执行完毕后再输出over!
	fmt.Println("over!")
}
// 输出:
// 这是一个goroutine the second goroutine!
// 这是一个goroutine the first goroutine!
// 这是一个goroutine the first goroutine!
// 这是一个goroutine the second goroutine!
// 这是一个goroutine the second goroutine!
// over!

并发执行

​ 前文说过,并发执行就是让协程运行在同一个逻辑处理器上,我们可以在主方法中使用runtime.GOMAXPROCS(1)强制控制在一个逻辑处理器中

// main方法
func main() {
    routine.GOMAXPROCS(1)
    // 实例化计数器wg
	var wg sync.WaitGroup
    // 要运行两个goroutine函数
	wg.Add(2)
	go functions.Demo01(2, "the first goroutine!", &wg)
	go functions.Demo01(3, "the second goroutine!", &wg)
    // 等待两个goroutine运行完毕
	wg.Wait()
    // 执行完毕后再输出over!
	fmt.Println("over!")
}

​ 这样子会让处理器在两个工作中不断的切换,而并不是真正的同时进行,而真正的同进行,需要并行执行

并行执行

​ 并行执行就是让各个goroutine都在单独的逻辑处理器中运行,这时runtime.GOMAXPROCS(tmp)中的tmp参数就应给等于你的goroutine个数,同时我们可以使用runtime.NumCPU()来返回自己电脑中的物理处理器个数,而物理处理器的个数是和自己电脑的处理器挂钩的

// main方法
func main() {
    routine.GOMAXPROCS(2)
    fmt.Println(runtime.NumCPU()) // 20
    // 实例化计数器wg
	var wg sync.WaitGroup
    // 要运行两个goroutine函数
	wg.Add(2)
	go functions.Demo01(2, "the first goroutine!", &wg)
	go functions.Demo01(3, "the second goroutine!", &wg)
    // 等待两个goroutine运行完毕
	wg.Wait()
    // 执行完毕后再输出over!
	fmt.Println("over!")
}

​ 通过并行执行,我们就可以保证不同的协程是同时运行在不同的逻辑处理器当中,可以实行同时运行文章来源地址https://www.toymoban.com/news/detail-425754.html

到了这里,关于Go语言入门12(协程 goroutine)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 操作系统进程线程(一)—进程线程协程区别、多进程多线程、进程调度算法、进程线程通信

    定义上 进程: 资源分配和拥有 的基本单位,是调度的基本单位。 运行一个可执行程序会创建一个或者多个进程;进程就是运行起来的程序 线程:程序 执行 基本单位,轻量级进程。 每个进程中都有唯一的主线程 ,主线程和进程是相互依赖的关系。 协程: 用户态 的轻量级

    2024年02月01日
    浏览(23)
  • 线程 进程 协程 区别

    在并发编程中,\\\"线程\\\"和\\\"协程\\\"都是用于实现并发执行的概念,但它们有一些重要的区别。 线程(Thread): 线程是操作系统的概念,是操作系统调度的最小执行单位,是进程中的一个实体,表示程序执行的基本单元。 线程由操作系统内核调度和管理,它拥有自己的执行上下文

    2024年02月04日
    浏览(46)
  • 进程,线程,协程

    1、进程 进程是具有一定独立功能的程序关于某个​​数据集​​合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销

    2024年02月11日
    浏览(27)
  • 什么是进程、线程、协程

    我们都知道计算机的核心是CPU,它承担了所有的计算任务;而操作系统是计算机的管理者,它负责任务的调度、资源的分配和管理,统领整个计算机硬件;应用程序则是具有某种功能的程序,程序是运行于操作系统之上的。 进程是一个具有一定独立功能的程序在一个数据集上

    2024年02月13日
    浏览(17)
  • Linux的进程,协程和线程

    Linux的进程、协程和线程是计算机科学中重要的概念,它们在操作系统和并发编程中发挥着关键的作用。让我们逐个详解这些概念,并讨论它们之间的关系。 进程是操作系统中的一个执行单元,它包含了程序执行所需的所有资源,如内存空间、文件描述符、寄存器等。 进程是

    2024年01月23日
    浏览(21)
  • Python多任务教程:进程、线程、协程

    进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进

    2024年02月12日
    浏览(22)
  • 1.Unity协程、进程、线程的区别

    1、 进程 拥有自己独立的堆和栈,堆和栈都不共享,进程由操作系统调度。 2、 线程 有自己独立的栈和共享的堆,栈不共享,堆共享,标准的线程也是由系统调度。 3、 协程 有自己独立的栈和共享的堆,栈不共享,堆共享,协程由程序员在协程的代码里面调度。 协程多与线

    2024年02月03日
    浏览(25)
  • Go语言入门记录:从基础到变量、函数、控制语句、包引用、interface、panic、go协程、Channel、sync下的waitGroup和Once等

    程序入口文件的包名必须是main,但主程序文件所在文件夹名称不必须是 main ,即我们下图 hello_world.go 在 main 中,所以感觉 package main 写顺理成章,但是如果我们把 main 目录名称改成随便的名字如 filename 也是可以运行的,所以迷思就在于写在文件开头的那个 package main 和 java

    2024年02月11日
    浏览(19)
  • 【Python】多线程编程 ① ( 线程相关概念 | 进程 | 线程 | 协程 / 纤程 | 管程 )

    进程 与 操作系统 : 进程 是 操作系统 中 能够独立运行的单元 , 是 操作系统 对 正在运行的 应用程序 的 抽象结构 描述 ; 操作系统 中 运行的每个 应用程序 就是一个进程 ; 一个操作系统中可以运行 多个 进程 ; 每个 应用程序 都会被 操作系统 分配一个 进程 ID ; 多个进程之间

    2024年02月15日
    浏览(17)
  • 7 文件操作、单元测试、goroutine【Go语言教程】

    1.1 介绍 os.File 封装所有文件相关操作,File 是一个结构体 常用方法: 打开文件 关闭文件 1.2 应用实例 ①读文件 常用方法: ①bufio.NewReader(), reader.ReadString【带缓冲】 ②io/ioutil【一次性读取,适用于小文件】 读取文件的内容并显示在终端(带缓冲区的方式),使用 os.Open, file.

    2024年02月04日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包