3.21 Go之多核并行化

3.21 Go之多核并行化

并发和并行的概念

首先了解什么是并发什么是并行

Go当中实现多核多线程并发

注意:

注意区分什么是goroutine在并发和并行章节已经提到了.

获取当前操作系统CPU的核心数:

示例代码:

package main

import (
   "fmt"
   "runtime"
)

/*
调用runtime包下的函数获取到当前操作系统的cpu核心数
*/
func main() {
   cpuNum := runtime.NumCPU()
   fmt.Println("cpu核心数为:", cpuNum)

   /* 循环调用函数开启线程--->使用go关键字 */
   for i := 0; i < 5; i++ {
       go func(index int) {
           sum := 0
           for j := 0; j < 10000; j++ {
               sum += 1
          }
           fmt.Printf("线程%d, sum值为:%d\n", index, sum)
      }(i)
  }
}

注意:

在调用的时候不能直接使用传统的go run命令,需要使用go run -race命令才能看到goroutine当中的结果

模拟并行计算任务

计算 N 个整型数的总和。
将所有整型数分成 M 份,M 即 CPU 的个数。让每个 CPU 开始计算分给它的那份计算任务,最后将每个 CPU 的计算结果再做一次累加,
得到所有 N 个整型数的总和

示例代码:

package main

import "runtime"

type Vector []float64

// Op函数是一个公共累加函数
func (v Vector) Op(num float64) float64 {
   num = 1
   return num
}

// 该类型实现的函数(执行运算函数)
func (v Vector) DoSome(i, n int, u Vector, c chan int) {
   // 循环开启协程
   for ;  i < n ; i++ {
       v[i] += u.Op(v[i])
  }
   // 将结果传输回到channel当中
   c <- 1
}

// 设置Cpu数量
var Ncpu = runtime.NumCPU()
const NCPU = 8 // 这里注意常量和变量的区别,变量的声明和赋值不能够传递给常量

// 该类型分配的函数(分配cpu函数)
func (v Vector) DoAll(u Vector) {
   // 声明任务完成的通道,该通道是个缓冲通道,缓冲通道
   /*
   这里注意make和new的区别
   make:返回的是创建的对象本身
   new:返回的是创建的对象的指针
    */
   c := make(chan int, NCPU)

   // 循环调用DoSome函数执行计算过程
   for i := 0; i < NCPU; i++ {
       go v.DoSome(i*len(v)/NCPU, (i+1)*len(v)/NCPU, u, c)
  }

   // 等待所有cpu完成任务将数据放入缓冲通道
   for i := 0; i < NCPU; i++ {
       <-c // 匿名接收
  }
}

注意:

  • 实际上所有这些goroutine都运行在同一个CPU核心上,在一个goroutine得到时间片执行的时候,其他goroutine都会处于等待状态。

posted @   俊king  阅读(244)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示