当前位置: 首页 > news >正文

广东网站建设教程成都网页设计培训学校哪家好

广东网站建设教程,成都网页设计培训学校哪家好,设一个网站需要多少钱,深圳制作网站流程参考#xff1a;逐步学习Go-协程goroutine – FOF编程网 什么是线程#xff1f; 简单来说线程就是现代操作系统使用CPU的基本单元。线程基本包括了线程ID#xff0c;程序计数器#xff0c;寄存器和线程栈。线程共享进程的代码区#xff0c;数据区和操作系统的资源。 线… 参考逐步学习Go-协程goroutine – FOF编程网 什么是线程 简单来说线程就是现代操作系统使用CPU的基本单元。线程基本包括了线程ID程序计数器寄存器和线程栈。线程共享进程的代码区数据区和操作系统的资源。 线程为什么很“重” 因为线程会有很多上下文操作系统需要调度线程执行不能让一个线程执行完才执行另一个线程那其他线程就“饿死”了。线程调度就涉及线程切换停止当前正在运行的线程保存线程的状态上下文选择另一个线程并加载这个上下文并执行这个线程。线程切换比较耗时因为内核或者操作系统级别的线程有很多上下文主要涉及的切换有 程序计数器寄存器CPU缓存CPU调度线程状态管理… 所以线程切换比较耗时。 什么是协程 协程并不是一个新概念了协程已经被很多语言使用了比如Java 19的VirtualThreadPython的asyncio, JavaScript ES6中的async/await, C#, Kotlin,… 协程就是轻量级线程,协程和操作系统的重量级线程的关系是M:N一般M\N。减少调度和切换开销。 协程还有什么优势 内存占用小据Go说Go创建一个协程只需要2KB内存切换成本低线程切换只涉及用户程序的调度不涉及线程哪些切换的内容所以很快创建销毁快用户程序创建和销毁所以很快 协程和线程的映射关系 我们可以把线程是协程的CPU协程需要执行需要调度到某个线程上执行。 协程最终还是使用线程来执行所以协程需要对应一个线程来执行自己的代码那么这个映射关系是什么 一对一一对多多对一多对多 一对一 如何来理解一对一关系我觉得这是在某一时刻一个协程都由一个线程来管理和执行。 一对多 如果理解一对多关系我觉得这是在一个时间段内一个协程可能会被调度到多个线程上执行但是在某一个时间点一个协程不会被调度到两个或者更多线程执行。 多对一 如何理解多对一关系我觉得是多个协程在一个时间段内会被调度到同一个线程执行。 多对多 协程运行时是M:N模型就是M个协程映射到N个线程上。 Go中的协程 进入正题Go中提供了协程模型和API没有可以直接操作的线程模型和API。 Go的协程特性 Go的协程遵守我们上面提到的协程特性 轻量级并发执行异步执行复用这个复用指的是复用操作系统线程协程之间通过Channel通信和同步非抢占式调度Go的协程调度器使用的是非抢占式调度模型这就表示协程在运行期间是不可中断的只有协程自己让出CPU比如协程休眠I/O之类的操作协程才会让出CPU高效上下文切换优雅关闭不阻塞主线程主线程退出协程也会退出 环境 我们使用go testing和testify来编写测试用例进行协程特性演示。 testify直接使用go get安装就可以了。 go get github.com/stretchr/testify COPY 这是import的模块 import (fmtruntimetestinggithub.com/stretchr/testify/assert )COPY 创建协程 go中创建协程不需要写接口不需要写struct只需要一个go关键字执行函数就可以了。 go标准函数go闭包/匿名函数go方法structinterface{}反射如有其他方式请留言告知 go标准函数创建协程 我们先来创建一个Go函数参数传入一个channel方便我们对channel进行同步控制 // 标准Go函数 func standardFunc(ch chan bool) {println(Hello, Standard Function Go Routine)ch - true }COPY 我们来创建一个Go协程来执行这个标准函数 // 标准函数创建协程 func TestRoutine_ShouldSuccess_WhenCreateWithStandardFunction(t *testing.T) {ch : make(chan bool)// func为标准函数go standardFunc(ch)ret : -chassert.True(t, ret) } COPY 执行截图 go闭包/匿名函数创建协程 这种方式比较方便 // 闭包/匿名函数创建协程 func TestRoutine_ShouldSuccess_WhenCreateWithAnonymousFunction(t *testing.T) {ch : make(chan bool)// func为闭包/匿名函数go func() {println(Hello, Anonymous Function Go Routine)ch - true}()ret : -chassert.True(t, ret) } COPY 执行截图 go方法struct创建协程 我们先定义一个struct,struct有一个channel方便我们进行等待协程执行完成 type s struct {ch chan bool } COPY 我们定义两个方法run和waitrun来执行业务wait等待run执行完成: type s struct {ch chan bool }func (s *s) run() {println(Hello, Struct Method Go Routine)s.ch - true }func (s *s) wait() {-s.ch } COPY 我们来创建一个协程执行我们的run方法和wait方法 func TestRoutine_ShouldSuccess_whenCreateWithStructMethod(t *testing.T) {// 定义struct变量s : s{ch: make(chan bool),}// 创建协程go s.run()// 等待执行完成s.wait() }} COPY 运行截图 interface{}反射创建协程 我觉得这种方式超级复杂但是实际业务场景中也特别有用。相当于你可以开发一个调度器别人提交任务和任务的参数给你你来控制怎么来调度。 看代码 我们先定义一个调度函数参数f是函数args是f的参数。 func scheduleFunc(wg *sync.WaitGroup, f interface{}, args ...interface{}) {// 通过反射获取函数的定义funcVal : reflect.ValueOf(f)// 然后获取函数的参数// 使用循环把参数加入到slice中in : make([]reflect.Value, len(args))for k, param : range args {in[k] reflect.ValueOf(param)}wg.Add(1)// 创建调用函数// 我们这儿用匿名函数包装了一下go func() {defer wg.Done() funcVal.Call(in)}() } COPY 然后我们定义两个任务函数, task1和task2: func task1(a string) {fmt.Printf(Hello: %s\n, a) }func task2(a, b string) {fmt.Printf(Hello: %s-%s\n, a, b) }COPY 最后我们来测试一下 func TestRoutine_ShouldSuccess_whenCreateWithReflect(t *testing.T) {var wg sync.WaitGroup // 创建一个 WaitGroupscheduleFunc(wg, task1, Hello, goroutine!)scheduleFunc(wg, task2, Hello, goroutine!)wg.Wait() // 等待所有 goroutine 结束} COPY 运行截图 package mainimport (fmtreflect )func worker(data []interface{}) {funcName : data[0].(string)funcArgs : data[1:] // Function or method argumentsfuncValue : reflect.ValueOf(funcMap[funcName])funcArgsValues : make([]reflect.Value, len(funcArgs))for i, arg : range funcArgs {funcArgsValues[i] reflect.ValueOf(arg)}go funcValue.Call(funcArgsValues) }var funcMap map[string]interface{}{printFunc: printFunc,printSum: printSum, }func printFunc(s string) {fmt.Println(s) }func printSum(a, b int) {fmt.Println(a b) }func main() {worker([]interface{}{printFunc, Hello, World!})worker([]interface{}{printSum, 1, 2})// Sleep to wait for goroutines to finishfor {} } COPY 设置线程和协程的数量对应关系 默认线程数量 // 获取Go协程使用的线程数量 func TestGPROC_ShouldReturnDefaultNumer_WhenNotSetProcNumber(t *testing.T) {// 如果GOMAXPROCS()的参数为0则是获取线程数量大于0就是设置线程数量procnum : runtime.GOMAXPROCS(0)fmt.Printf(default proc number: %d\n, procnum) } COPY 设置线程数量 使用代码设置线程数需要使用runtime.GOMAXPROCS设置线程数量 // 获取Go协程使用的线程数量 func TestGPROC_ShouldReturnSpecificNumer_WhenSetProcNumber(t *testing.T) {specnum : 4// 设置线程数量为4// 如果GOMAXPROCS()的参数为0则是获取线程数量runtime.GOMAXPROCS(specnum)fmt.Printf(set proc number: %d\n, specnum)assert.Equal(t, specnum, runtime.GOMAXPROCS(0)) } COPY 环境变量设置 在程序启动前设置环境变量GOMAXPROCS就可以了。 export GOMAXPROCS4COPY 关闭协程 自行结束手动取消 自行结束 这个和线程类似协程执行完了就退出了我们上面的例子都是协程执行完了自动退出。 手动取消 手动取消就需要增加控制机制了我们来列两个手动取消的例子 context传递取消信号channel发送取消信号 我们先来定义一个后台任务,这个后台任务每个一秒钟打印一条“Hello background task” // 不用太关注api和语法只需要知道每个一秒钟打印Hello background task func backgroundTask(ctx context.Context) {ticker : time.NewTicker(1 * time.Second)defer ticker.Stop()for {select {case -ctx.Done(): // 接收到取消信号结束 goroutinereturncase -ticker.C: // 每次 ticker 到时打印一条消息println(Hello background task)}} } COPY context传递取消信号 直接上代码 func TestRoutine_ShouldStop_whenSendCancelWithContext(t *testing.T) {ctx, cancel : context.WithCancel(context.Background())go backgroundTask(ctx)// 让 协程 运行一段时间time.Sleep(time.Second * 5)// 发送取消信号cancel()// 给协程留一点时间处理信号time.Sleep(time.Second * 2) } COPY 运行截图 channel发送取消信号 直接上代码 func signaltask(ch chan bool) {for {select {// 接收到取消信号结束协程case -ch:return// 没有接收到取消信号打印一条消息default:println(Hello signal task)time.Sleep(time.Second * 1)}} } func TestRoutine_ShouldStop_WhenSendCancelSignal(t *testing.T) {ch : make(chan bool)go signaltask(ch)// 让协程运行5秒钟time.Sleep(time.Second * 5)// 发送取消信号ch - true// 给协程留一点时间处理信号time.Sleep(time.Second * 2) } COPY 运行截图 搞定收工如有错误请留言告知
http://www.zqtcl.cn/news/979245/

相关文章:

  • 深圳网站seo推广河北建设工程信息网停用公告
  • 给公司建网站 深圳wordpress去掉cat
  • 网站建设推荐华网天下土巴兔装修平台怎么收费
  • 微网站 网页成品网站模块
  • soap公司网站wordpress 相关推荐
  • 浙江质监站网址固始网站建设公司
  • 济南 外贸网站建设怎么知道网站是哪个公司做的
  • 分享wordpress优秀主题东莞百度seo找谁
  • 顺德网站制作案例价位超兽vps群
  • 网站建设 搜狐号电脑赚钱的项目有哪些
  • 做生意的网站广州互联网企业100强
  • 网站单页支付宝支付怎么做网站制作公司套路
  • 本网站维护升级官方网站建设滞后
  • 网站上漂亮的甘特图是怎么做的江门seo方法
  • 局域网建设网站seo优化查询
  • 网站安装模板wordpress多个函数文件
  • 网站建设飠金手指排名十二毕业设计论文网
  • 高密哪里做网站好网络营销的四大特点
  • 网站锚文本怎么做怎么在网上接网站建设
  • php做公司网站中国大工程建设需要什么样的人才
  • 优化公司怎么优化网站的技能网站建设项目需求
  • wordpress怎么修改主页网站改版seo
  • 做视频网站需要多少带宽lnmp wordpress 数据库
  • 网站速度慢wordpress徐州网络推广公司
  • 网站建设增城seo外链是什么意思
  • php做企业网站管理系统免费网站制作手机软件的app
  • 商城网站建设咨询如何通过网站后台修改网站
  • 重庆网站建设论文2 如何写一份详细的网站开发方案
  • 宁波门户网站建设做购物网站表结构分析
  • 上传网站图片处理画册设计多少钱一页