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

上海机械网站建设自由型的网站

上海机械网站建设,自由型的网站,wordpress atom,做网站一个人能做吗本文原文地址:GoLang协程Goroutiney原理与GMP模型详解 什么是goroutine Goroutine是Go语言中的一种轻量级线程#xff0c;也成为协程#xff0c;由Go运行时管理。它是Go语言并发编程的核心概念之一。Goroutine的设计使得在Go中实现并发编程变得非常简单和高效。 以下是一些…本文原文地址:GoLang协程Goroutiney原理与GMP模型详解 什么是goroutine Goroutine是Go语言中的一种轻量级线程也成为协程由Go运行时管理。它是Go语言并发编程的核心概念之一。Goroutine的设计使得在Go中实现并发编程变得非常简单和高效。 以下是一些关于Goroutine的关键特性 轻量级Goroutine的创建和切换开销非常小。与操作系统级别的线程相比Goroutine占用的内存和资源更少。一个典型的Goroutine只需要几KB的栈空间并且栈空间可以根据需要动态增长。并发执行Goroutine可以并发执行多个任务。Go运行时会自动将Goroutine调度到可用的处理器上执行从而充分利用多核处理器的能力。简单的语法启动一个Goroutine非常简单只需要在函数调用前加上go关键字。例如go myFunction()会启动一个新的Goroutine来执行myFunction函数。通信和同步Go语言提供了通道Channel机制用于在Goroutine之间进行通信和同步。通道是一种类型安全的通信方式可以在不同的Goroutine之间传递数据。 什么是协程 协程Coroutine是一种比线程更轻量级的并发编程方式。它允许在单个线程内执行多个任务并且可以在任务之间进行切换而不需要进行线程上下文切换的开销。协程通过协作式多任务处理来实现并发这意味着任务之间的切换是由程序显式控制的而不是由操作系统调度的。 以下是协程的一些关键特性 轻量级协程的创建和切换开销非常小因为它们不需要操作系统级别的线程管理。非抢占式协程的切换是显式的由程序员在代码中指定而不是由操作系统抢占式地调度。状态保存协程可以在暂停执行时保存其状态并在恢复执行时继续从暂停的地方开始。异步编程协程非常适合用于异步编程特别是在I/O密集型任务中可以在等待I/O操作完成时切换到其他任务从而提高程序的并发性和效率。 Goroutin就是Go在协程这个场景上的实现。 以下是一个简单的go goroutine例子展示了如何使用协程 package mainimport (fmtsynctime )// 定义一个简单的函数模拟一个耗时操作 func printNumbers(wg *sync.WaitGroup) {defer wg.Done() // 在函数结束时调用Done方法for i : 1; i 5; i {fmt.Printf(Number: %d\n, i)time.Sleep(1 * time.Second) // 模拟耗时操作} }func main() {var wg sync.WaitGroup// 启动一个goroutine来执行printNumbers函数wg.Add(1)go printNumbers(wg)// 主goroutine继续执行其他操作for i : A; i E; i {fmt.Printf(Letter: %c\n, i)time.Sleep(1 * time.Second) // 模拟耗时操作}// 等待所有goroutine完成wg.Wait() }我们定义了一个名为printNumbers的函数该函数会打印数字1到5并在每次打印后暂停1秒。然后在main函数中我们使用go关键字启动一个新的goroutine来执行printNumbers函数。同时主goroutine继续执行其他操作打印字母A到E并在每次打印后暂停1秒。 需要注意的是主goroutine和新启动的goroutine是并发执行的。为了确保所有goroutine完成我们使用sync.WaitGroup来等待所有goroutine完成。我们在启动goroutine之前调用wg.Add(1)并在printNumbers函数结束时调用wg.Done()。最后我们在main函数中调用wg.Wait()等待所有goroutine完成。这样可以确保程序在所有goroutine完成之前不会退出。 协程是一种强大的工具可以简化并发编程特别是在处理I/O密集型任务时。 Goroutin实现原理 Goroutine的实现原理包括Goroutine的创建、调度、上下文切换和栈管理等多个方面。通过GPM模型和高效的调度机制Go运行时能够高效地管理和调度大量的Goroutine实现高并发编程。 Goroutine的创建 当使用go关键字启动一个新的Goroutine时Go运行时会执行以下步骤 分配G结构体Go运行时会为新的Goroutine分配一个G结构体G表示Goroutine其中包含Goroutine的状态信息、栈指针、程序计数器等。分配栈空间Go运行时会为新的Goroutine分配初始的栈空间通常是几KB。这个栈空间是动态增长的可以根据需要自动扩展。初始化G结构体Go运行时会初始化G结构体将Goroutine的入口函数、参数、栈指针等信息填入G结构体中。将Goroutine加入调度队列Go运行时会将新的Goroutine加入到某个PProcessor的本地运行队列中等待调度执行。 Goroutine的调度 Go运行时使用GPM模型Goroutine、Processor、Machine来管理和调度Goroutine。调度过程如下 PProcessorP是Go运行时的一个抽象概念表示一个逻辑处理器。每个P持有一个本地运行队列用于存储待执行的Goroutine。P的数量通常等于机器的CPU核心数可以通过runtime.GOMAXPROCS函数设置。MMachineM表示一个操作系统线程。M负责实际执行P中的Goroutine。M与P是一对一绑定的关系一个M只能绑定一个P但一个P可以被多个M绑定通过抢占机制。M的数量是由Go运行时系统动态管理和确定的。M的数量并不是固定的而是根据程序的运行情况和系统资源的使用情况动态调整的。通过runtime.NumGoroutine()和runtime.NumCPU()函数我们可以查看当前的Goroutine数量和CPU核心数。Go运行时对M的数量有一个默认的最大限制以防止创建过多的M导致系统资源耗尽。这个限制可以通过环境变量GOMAXPROCS进行调整但通常不需要手动设置。GGoroutine代表一个goroutine它有自己的栈instruction pointer和其他信息正在等待的channel等等用于调度。调度循环每个P会在一个循环中不断从本地运行队列中取出Goroutine并将其分配给绑定的M执行。如果P的本地运行队列为空P会尝试从其他P的本地运行队列中窃取Goroutine工作窃取机制。 从上图中看有2个物理线程M每一个M都拥有一个处理器P每一个也都有一个正在运行的goroutine。P的数量可以通过GOMAXPROCS()来设置它其实也就代表了真正的并发度即有多少个goroutine可以同时运行。图中灰色的那些goroutine并没有运行而是出于ready的就绪态正在等待被调度。P维护着这个队列称之为runqueueGo语言里启动一个goroutine很容易go function 就行所以每有一个go语句被执行runqueue队列就在其末尾加入一个goroutine在下一个调度点就从runqueue中取出如何决定取哪个goroutine一个goroutine执行。 P的数量可以大于器的CPU核心数 在Go语言中PProcessor的数量通常等于机器的CPU核心数但也可以通过runtime.GOMAXPROCS函数进行调整。默认情况下Go运行时会将P的数量设置为机器的逻辑CPU核心数。然而P的数量可以被设置为大于或小于机器的CPU核心数这取决于具体的应用需求和性能考虑。 调整P的数量可以使用runtime.GOMAXPROCS函数来设置P的数量。例如 package mainimport (fmtruntimesync )func worker(id int, wg *sync.WaitGroup) {defer wg.Done()fmt.Printf(Worker %d starting\n, id)// 模拟工作负载for i : 0; i 1000000000; i {}fmt.Printf(Worker %d done\n, id) }func main() {// 设置P的数量为机器逻辑CPU核心数的两倍numCPU : runtime.NumCPU()runtime.GOMAXPROCS(numCPU * 2)var wg sync.WaitGroup// 启动多个Goroutinefor i : 1; i 10; i {wg.Add(1)go worker(i, wg)}// 等待所有Goroutine完成wg.Wait()fmt.Println(All workers done) }在这个示例中我们将P的数量设置为机器逻辑CPU核心数的两倍。这样做的目的是为了观察在不同P数量设置下程序的性能表现。 P的数量大于CPU核心数的影响 上下文切换增加当P的数量大于CPU核心数时可能会导致更多的上下文切换。因为操作系统需要在有限的CPU核心上调度更多的线程M这可能会增加调度开销。资源竞争更多的P意味着更多的Goroutine可以同时运行但这也可能导致更多的资源竞争特别是在I/O密集型任务中。过多的P可能会导致资源争用反而降低程序的整体性能。并发性提高在某些情况下增加P的数量可以提高程序的并发性特别是在存在大量阻塞操作如I/O操作的情况下。更多的P可以更好地利用CPU资源减少阻塞时间。 P的数量小于CPU核心数的影响 CPU利用率降低当P的数量小于CPU核心数时可能会导致CPU资源未被充分利用。因为P的数量限制了同时运行的Goroutine数量可能会导致某些CPU核心处于空闲状态。减少上下文切换较少的P数量可以减少上下文切换的开销因为操作系统需要调度的线程M数量减少。这可能会提高CPU密集型任务的性能。 选择合适的P数量选择合适的P数量需要根据具体的应用场景和性能需求进行调整。以下是一些建议 CPU密集型任务对于CPU密集型任务通常将P的数量设置为等于或接近机器的逻辑CPU核心数以充分利用CPU资源。I/O密集型任务对于I/O密集型任务可以考虑将P的数量设置为大于CPU核心数以提高并发性和资源利用率。性能测试和调优通过性能测试和调优找到最佳的P数量设置。可以尝试不同的P数量观察程序的性能表现选择最优的配置。 Goroutine的上下文切换 Goroutine的上下文切换由Go运行时的调度器管理主要涉及以下步骤 保存当前Goroutine的状态当一个Goroutine被挂起时Go运行时会保存当前Goroutine的状态信息包括程序计数器、栈指针、寄存器等。切换到新的GoroutineGo运行时会从P的本地运行队列中取出下一个待执行的Goroutine并恢复其状态信息。恢复新的Goroutine的状态Go运行时会将新的Goroutine的状态信息加载到CPU寄存器中并跳转到新的Goroutine的程序计数器位置继续执行。 Goroutine什么时候会被挂起Goroutine会在执行阻塞操作、使用同步原语、被调度器调度、创建和销毁时被挂起。Go运行时通过高效的调度机制管理Goroutine的挂起和恢复以实现高并发和高性能的程序执行。了解这些挂起的情况有助于编写高效的并发程序并避免潜在的性能问题。 阻塞操作 当Goroutine执行阻塞操作时它会被挂起直到阻塞操作完成。常见的阻塞操作包括 I/O操作如文件读写、网络通信等。系统调用如调用操作系统提供的阻塞函数。Channel操作如在无缓冲Channel上进行发送或接收操作时如果没有对应的接收者或发送者Goroutine会被挂起。 同步原语 使用同步原语如sync.Mutex、sync.WaitGroup、sync.Cond等进行同步操作时Goroutine可能会被挂起直到条件满足。例如 互斥锁Mutex当Goroutine尝试获取一个已经被其他Goroutine持有的互斥锁时它会被挂起直到锁被释放。条件变量Cond当Goroutine等待条件变量时它会被挂起直到条件变量被通知。 调度器调度 Go运行时的调度器会根据需要挂起和恢复Goroutine以实现高效的并发调度。调度器可能会在以下情况下挂起Goroutine 时间片用完Go调度器使用协作式调度当一个Goroutine的时间片用完时调度器会挂起该Goroutine并调度其他Goroutine执行。主动让出Goroutine可以通过调用runtime.Gosched()主动让出CPU调度器会挂起该Goroutine并调度其他Goroutine执行。 Goroutine的创建和销毁 创建当一个新的Goroutine被创建时它会被挂起直到调度器将其调度执行。销毁当一个Goroutine执行完毕或被显式终止时它会被挂起并从调度器中移除。 Goroutine的栈管理 Goroutine的栈空间是动态分配的可以根据需要自动扩展。Go运行时使用分段栈segmented stack或连续栈continuous stack来管理Goroutine的栈空间 分段栈在早期版本的Go中Goroutine使用分段栈。每个Goroutine的栈由多个小段组成当栈空间不足时Go运行时会分配新的栈段并链接到现有的栈段上。连续栈在Go 1.3及以后的版本中Goroutine使用连续栈。每个Goroutine的栈是一个连续的内存块当栈空间不足时Go运行时会分配一个更大的栈并将现有的栈内容复制到新的栈中。
http://www.w-s-a.com/news/277159/

相关文章:

  • 深圳营销型定制网站开发1000建设银行网站特点分析
  • 安装网站系统重庆知名网站
  • 巴彦淖尔市 网站建设怀化北京网站建设
  • 内部网站管理办法建立网站后台
  • 自学考试网站建设与管理郑州网站建设开拓者
  • 宁夏制作网站公司慈溪建设集团网站
  • 国家企业官方网站查询系统站酷设计网站官网入口文字设计
  • 彩票网站开发制作需要什么wordpress连接微博专业版v4.1
  • 孝感建设银行官网站百度一下你就知道啦
  • 做网站如何做视频广告制作公司简介怎么写
  • 做网站 买空间商务网站内容建设包括
  • 萝岗网站建设为什么点不开网站
  • 惠州网站制作询问薇北京网站建设最便宜的公司
  • 注册网站英语怎么说wordpress 3.8.3
  • 甘肃张掖网站建设网站开发软件是什么专业
  • 海口省建设厅网站网站数据库怎么做同步
  • 做网站建设月收入多少app开发公司广州英诺
  • 新闻播报最新网站优化外包费用
  • wordpress分页出现404最专业的seo公司
  • 连云港网站建设电话连云港市建设局网站
  • 平面设计网站有哪些比较好drupal网站建设 北京
  • 健康资讯网站模板网页价格表
  • 2008发布asp网站宝安建网站的公司
  • 郑州市城市建设管理局网站制作公司网站 优帮云
  • 网站开发 瀑布结构普陀网站建设
  • 12380网站建设情况汇报plone vs wordpress
  • c 网站开发数据库连接与wordpress类似的都有哪些
  • 状元村建设官方网站长春做网站seo的
  • 做金融资讯网站需要哪些牌照海珠营销型网站制作
  • 学做网站需要买什么书手机网络