「让我们一起Golang」怎样出让协程资源和设置可用CPU核心数

简介: 「让我们一起Golang」怎样出让协程资源和设置可用CPU核心数

「让我们一起Golang」怎样出让协程资源和设置可用CPU核心数

前面了解了协程的有关基础知识,了解了CPS并发模型,见识了Golang的百万级并发,下面我们来实现一下出让协程资源和设置可用CPU核心数。

出让协程资源

先看看执行结果:

子协程0 0
子协程0 1
子协程0 2
子协程0 3
子协程0 4
子协程0 5
子协程2 0
子协程2 1
子协程2 2
子协程2 3
子协程2 4
子协程2 5
子协程2 6
子协程2 7
子协程1 0
子协程0 6
子协程0 7
子协程1 1
子协程1 2
子协程1 3
子协程1 4
子协程1 5
子协程1 6
子协程1 7

我们可以看到先是子协程0打印内容,然后字协程2打印内容,然后出现了子协程1打印结果,之后又突然出现了子协程0,然后是子协程1打印结果。

为什么是这样呢?先别急,先看一看代码想一想为什么!

func main() {
    for i:=0;i<3;i++{
        go func(index int) {
            task("子协程"+strconv.Itoa(index))
        }(i)
    }
    time.Sleep(5 * time.Second)
}

func task(name string)  {
    for i:=0;i<8;i++{
        if name == "子协程1"{
            //Gosched yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically.
            runtime.Gosched()
        }
        fmt.Println(name,i)
    }
}

这段代码是先激活3条子协程,分别是子协程0、子协程1、子协程2。然后每条协程执行task函数,但是对子协程1执行runtime.Gosched()操作。

下面来介绍一下runtime.Gosched()Gosched 生成一个处理器,允许其他goroutine先运行。 它不会中止当前的 goroutine,因此当前的 goroutine 会自动恢复运行。它的作用就是会把当前协程的优先级降低。

我们知道三条协程是并发的。但是这里对协程1实施了runtime.Gosched(),这让子协程1出让了协程资源。所以最后打印输出的一定是子协程1。但是,并不是所有的子协程1都是最后执行打印操作。这里有一个子协程1在子协程0之前打印输出了。我们把协程的数量加大。将主函数里面的for循环范围从0~3改为0~108,我们会发现在最后打印的还是子协程1.(由于输出结果过多,在此不展示输出结果)但是要注意的是,如果是百万级并发,同时开辟一百万条协程,最后的可能就不是子协程1了,因为runtime.Gosched()虽然会降低协程的优先级,出让协程资源,但是并不一定让协程绝对的最后执行完毕。

设置可用CPU核心数

我们打开任务管理器,进入“性能”栏目,在CPU处右键选择“将图形更改为”,将“总体利用率”改为“逻辑处理器”。

image-20210801161637449

这里可以看到图片里面的CPU核数为八。

然后我们可用利用GO语言查看电脑CPU的核数。

package main

import (
    "fmt"
    "runtime"
)

func main() {

    fmt.Println("可用CPU核心数为",runtime.NumCPU())
    
    // GOMAXPROCS sets the maximum number of CPUs that can be executing
    // simultaneously and returns the previous setting. If n < 1, it does not
    // change the current setting.
    // The number of logical CPUs on the local machine can be queried with NumCPU.
    // This call will go away when the scheduler improves.
    fmt.Println("设置CPU的可用核数为1,先前的设置为",runtime.GOMAXPROCS(1))
}

使用runtime.NumCPU()打印即可。

而使用runtime.GOMAXPROCS(n)可以设置运行的最大核数。这里是设置CPU的可用最大核心数为1.而且该函数会有返回值返回先前的可用最大核心数。如果 n < 1,则不更改当前设置。

目录
相关文章
|
Kubernetes 监控 调度
在 Kubernetes 中应该如何设置 CPU 的 requests 和 limits
在 Kubernetes 中应该如何设置 CPU 的 requests 和 limits
212 0
|
监控 Go
Golang 语言 beego v2 之路由设置
Golang 语言 beego v2 之路由设置
219 0
|
1月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
69 4
|
1月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
41 4
Golang语言goroutine协程篇
|
2月前
|
NoSQL Unix 编译器
Golang协程goroutine的调度与状态变迁分析
文章深入分析了Golang中goroutine的调度和状态变迁,包括Grunnable、Gwaiting、Grunning和Gsyscall等状态,以及它们之间的转换条件和原理,帮助理解Go调度器的内部机制。
40 0
|
5月前
|
监控 负载均衡 算法
Golang深入浅出之-Go语言中的协程池设计与实现
【5月更文挑战第3天】本文探讨了Go语言中的协程池设计,用于管理goroutine并优化并发性能。协程池通过限制同时运行的goroutine数量防止资源耗尽,包括任务队列和工作协程两部分。基本实现思路涉及使用channel作为任务队列,固定数量的工作协程处理任务。文章还列举了一个简单的协程池实现示例,并讨论了常见问题如任务队列溢出、协程泄露和任务调度不均,提出了解决方案。通过合理设置缓冲区大小、确保资源释放、优化任务调度以及监控与调试,可以避免这些问题,提升系统性能和稳定性。
169 6
|
监控 数据挖掘 虚拟化
VMWare 虚拟机 CPU 设置里针对 CPU 的 虚拟化 CPU 性能计数器(U) 选项功能介绍
VMWare 虚拟机 CPU 设置里针对 CPU 的 虚拟化 CPU 性能计数器(U) 选项功能介绍
|
安全 虚拟化
VMWare 虚拟机 CPU 设置里针对 CPU 的虚拟化 IOMMU(IO 内存管理单元) 选项功能介绍
VMWare 虚拟机 CPU 设置里针对 CPU 的虚拟化 IOMMU(IO 内存管理单元) 选项功能介绍
|
5月前
|
Unix 应用服务中间件 Linux
nginx的CPU亲和性设置和优先级设置
nginx的CPU亲和性设置和优先级设置
|
5月前
|
C语言
start.S详解学习(一):设置 CPU 模式
start.S详解学习(一):设置 CPU 模式
82 0