go语言goroutine(代码片段)

两片空白 两片空白     2022-12-15     783

关键词:

前言

        go语言对于并发编程有原生的支持。

        如下代码:创建10个协程并发执行。

package main

import (
	"fmt"
	"time"
)

func main() 
	for i := 0; i < 10; i++ 
		go func(i int) 
			fmt.Printf("hello from goroutine %d\\n", i)
		(i)
	
	//main函数执行完,协程也会被终止,等待1秒,协程执行完
	time.Sleep(time.Second)

Courotine 协程:

1. go语言中开辟的实际是协程,协程是轻量级线程。作用和线程差不多,并发执行任务。

        在go语言中可以开辟很多协程,比如:1000个协程,但是开辟1000个线程消耗的资源就比较多了。

2. 协程为什么是轻量级线程。

        go语言中的协程是非抢占式多任务处理,由协程主动交出控制权。

        抢占式式多任务处理:操作系统由更高优先级的任务,可以停止当前执行的线程,去执行更高优先级线程。

        非抢占式多任务处理:操作系统不能主动去停止。而是由任务主动交出控制权。

        线程是抢占式多任务处理,所以等任务切换时,需要内存来保存程序执行的上下文。

        协程不需要那麽多内存来保存上下文,只需要保存切换点。

        协程是编译器/解释器/虚拟机层面的多任务,不是操作系统层面的多任务。操作系统层面没有协程,

        所以协程是轻量级线程。

3. 多个协程可能在一个或者多个线程上执行。

        我们知道操作系统有调度器,而go语言也有自己的调度器,来调度协程的运行。所以可能协程在不同的一个或者一个线程上运行。

参数传递给协程的注意点:

代码:

        每次开辟的协程参数i需要被传入,如果不传入,会出现越界错误。

        因为使用的i在全局只有一份,当i被加到10时,有的协程还没有运行完或者正在运行,此时i时同一个,再执行a[i]时,就越界了,作为参数传入,i会被拷贝一份,每个协程私有。

package main

import (
	"fmt"
	"time"
)

func main() 
	var a [10]int
	for i := 0; i < 10; i++ 
		go func(i int) 
			for 
				a[i]++
			
		(i)
        // 会吹按越界错误
		// go func() 
		// 	for 
		// 		a[i]++
		// 	
		// ()
	
	//main函数执行完,协程也会被终止,等待1秒,协程执行完
	time.Sleep(time.Second)
	fmt.Println(a)

可以在命令行中可以输入go run -race xxx, 查看访问冲突。

 

go语言的调度器

        子程序(普通函数)是协程的特例。

  1.  任何函数前加上go关键字,就能送给调度器调度,
  2.  虽然协程是非抢占式的,但是为了提高效率,调度器会在合适的点进行切换,不需要显示去切换。

一般的切换点:并不保存会切换,也不能保证在别的地方不切换。

  • I/O操作,Select
  • channel
  • 等待锁
  • 函数调用(有时)
  • runtime.Gosched(),显示切换

go语言的协程可能运行在一个线程里,也可能多个协程运行在一个线程里,也有可能多个协程在多个线程里,这由go语言调度器来决定。

 

go语言通道(chan)——goroutine之间通信的管道(代码片段)

Go语言通道(chan)——goroutine之间通信的管道如果说goroutine是Go语言程序的并发体的话,那么channels就是它们之间的通信机制。一个channels是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值信息。每个channel... 查看详情

19.go语言基础之并发(代码片段)

...windows中360在杀毒,同时你也在写代码)Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作系... 查看详情

go语言基础之并发(代码片段)

...多个任务并行:同一时刻执行多个任务Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作... 查看详情

go语言学习笔记—进阶—并发编程:为函数创建goroutine(代码片段)

使用go关键字为一个函数创建一个goroutine。函数与goroutine是一对多的关系,即可以为一个函数创建多个goroutine,一个goroutine必定只对应一个函数。为普通函数创建goroutine格式为一个go函数创建goroutine,写法如下:go... 查看详情

15.go语言“避坑”与技巧(代码片段)

...生错误的地方及Go语言本身的使用技巧进行总结和归纳。goroutine(Go语言并发)如何使用才更加高效?Go语言原生支持并发是被众人津津乐道的特性。goroutine早期是Inferno操作系统的一个试验性特性,而现在这个特性与操作系统一... 查看详情

go语言基础之并发(代码片段)

...和你朋友都在用微信和女朋友聊天)。Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作... 查看详情

go语言学习-goroutine(代码片段)

o语言有一个很重要的特性就是goroutine,我们可以使用goroutine结合channel来开发并发程序。并发程序指的是可以同时运行多个任务的程序,这里的同时运行并不一定指的是同一时刻执行,在单核CPU的机器下,在同一时刻只可能有一个... 查看详情

go语言8-goroutine和channel(代码片段)

GoroutineGo语言从语言层面上就支持了并发,这与其他语言大不一样。Go语言中有个概念叫做goroutine,这类似我们熟知的线程,但是更轻。进程、线程、协程进程和线程进程是程序在操作系统中的一次执行过程,系统进行资源分配... 查看详情

go语言系列之并发编程(代码片段)

...和你朋友都在用微信和女朋友聊天)。Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作... 查看详情

09.go语言并发(代码片段)

...runtime),从语言上支持了并发的特性。Go语言的并发通过goroutine特性完成。goroutine类似于线程,但是可以根据需要创建多个goroutine并发工作。goroutine是由Go语言的运行时调度完成,而线程是由操作系统调度完成。Go语言还提供chann... 查看详情

go语言并发与通道的运用(代码片段)

在go语言中我们可以使用goroutine开启并发。goroutine是轻量级线程,goroutine的调度是由Golang运行时进行管理的。goroutine语法格式:go函数名(参数列表)实例1:packagemainimport("fmt""time")funcsay(sstring)fori:=0;i< 查看详情

go并发编程基础-channel(代码片段)

协程(Goroutine)Go语言中没有线程的概念,只有协程,也称为goroutine。相比线程来说,协程更加轻量,一个程序可以随意启动成千上万个goroutine。goroutine被Goruntime所调度,这一点和线程不一样。也就是说,Go语言的并发是由Go自己... 查看详情

go36-16,17-goroutine(代码片段)

...讯的方式共享数据。更具体地说,它一般被用来在不同的goroutine之间传递数据。这篇主要讲goroutine是什么。简单来说,goroutine代表着并发编程模型中的用户级线程。调度器Go语言不但有着独特的并发编程模型,以及用户级线程goro... 查看详情

goroutine/gosched/goexit/gomaxprocs(代码片段)

goroutine//code_037_concurrency_goroutineprojectmain.gopackagemainimport("fmt""time")//并发,concurrency;并行,parallel;而Go从语言层面就支持了并行,而Go语言提供了自动垃圾回收机制。//goroutine说到底其实就是协程,执行goroutine只需极少的栈内存(大概是4~5K... 查看详情

go语言channel(代码片段)

多线程同步问题互斥锁互斥锁的本质是当一个goroutine访问的时候,其它goroutine都不能访问这样就能实现资源同步,但是在避免资源竞争的同时也降低了程序的并发性能.程序由原来的并发执行变成了串行案例:有一个打印函数,用于逐... 查看详情

go语言学习之路(代码片段)

...试RedisRedis简介Redis基本使用Go连接redisRedis连接池Go面试题goroutine和channel(275-283)协程goroutine管道channel协程配合管道的综合 查看详情

go语言学习之路(代码片段)

...试RedisRedis简介Redis基本使用Go连接redisRedis连接池Go面试题goroutine和channel(275-283)协程goroutine管道channel协程配合管道的综合 查看详情

go语言管道(代码片段)

...箭头 <- 。Channel是CSP模式的具体实现,用于多个goroutine通讯。其内部实现了同步,确保并发安全。Channel是线程安全的,先进先出,多个goroutine同时访问,不需要加锁,channel是有类型的,一个整数的channel只能存放整数 查看详情