golang中的并发和并行

golang中默认使用一个CPU,这时程序无法并发,只能是并发。因为始终只有一个CPU在运行。

package main
import (
        "fmt"
        "runtime"
)

//并发和并行
var quit chan int = make(chan int)
func loop() {
        for i := 0; i < 100; i++ { //为了观察,跑多些
                fmt.Printf("%d ", i)
        }
        quit <- 0
}

func main() {
        runtime.GOMAXPROCS(2) // 最多使用2个核

        go loop()
        go loop()

        for i := 0; i < 2; i++ {
                <- quit
        }
}

runtime.GOMAXPROCS(2) 设置使用2个CPU,这才真正是并行。

补充:Go多核并行化

通过goroutine创建相同逻辑CPU核心个数的协程,将求和列表分段,分别计算后汇总。

通过runtime.NUMCPU()获得逻辑CPU个数,并计算每个协程中计算列表的下标,计算完成后,向channel中写入1。

通过向channel中读取int的个数,判断协程运行是否全部完成,之后求和即可。

package main
import (
	"fmt"
	"runtime"
)
type Vector []float64
func (v Vector) DoSome(p, i, n int, u Vector, c chan int) {
	sum := 0.0
	for ; i < n; i++ {
		sum += u[i]
	}
	v[p] = sum
	c <- 1
}
const NCPU = 4
func (v Vector) DoAll(u Vector) {
	c := make(chan int, NCPU)
	for i := 0; i < NCPU; i++ {
		fmt.Println(i, i*len(u)/NCPU, (i+1)*len(u)/NCPU)
		go v.DoSome(i, i*len(u)/NCPU, (i+1)*len(u)/NCPU, u, c)
	}
	for i := 0; i < NCPU; i++ {
		<-c
	}
	sum := 0.0
	for _, value := range v {
		sum += value
	}
	fmt.Println(sum)
}
func main() {
	u := make([]float64, 64)
	for i := 0; i < 64; i++ {
		u[i] = float64(i)
	}
	var v Vector = make([]float64, NCPU)
	v.DoAll(u)
	ncpu := runtime.NumCPU()
	fmt.Println(ncpu)
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • 浅谈golang并发操作变量安全的问题

    我就废话不多说了,大家还是直接看代码吧~ package main import ( "fmt" "time" "sync" "sync/atomic" ) func main() { test1() test2() } func test1() { var wg sync.WaitGroup count := 0 t := time.Now() for i := 0 ; i < 50000 ; i++ { wg.Add

  • golang 并发编程之生产者消费者详解

    golang 最吸引人的地方可能就是并发了,无论代码的编写上,还是性能上面,golang 都有绝对的优势 学习一个语言的并发特性,我喜欢实现一个生产者消费者模型,这个模型非常经典,适用于很多的并发场景,下面我通过这个模型,来简单介绍一下 golang 的并发编程 go 并发语法 协程 go 协程是 golang 并发的最小单元,类似于其他语言的线程,只不过线程的实现借助了操作系统的实现,每次线程的调度都是一次系统调用,需要从用户态切换到内核态,这是一项非常耗时的操作,因此一般的程序里面线程太多会

  • 快速解决Golang Map 并发读写安全的问题

    一.错误案例 package main import ( "fmt" "time" ) var TestMap map[string]string func init() { TestMap = make(map[string]string, 1) } func main() { for i := 0; i < 1000; i++ { go Write("aaa") go Read("aaa") go Write(&qu

  • Golang 并发以及通道的使用方式

    Golang最擅长的就是并发编程,使用Golang可以很方便的进行并发编程.先看一段普通的代码 package main import ( "fmt" "time" ) func Foo(i int) { fmt.Printf("%d will sleep\n", i) time.Sleep(5 * time.Second) fmt.Printf("%d wake up\n", i) } func main() { for i

  • 使用golang编写一个并发工作队列

    其实golang用一个函数可以构建一个并发队列,现在编写一个灵活可控的队列程序 先定义一个工作 type Worker struct { ID int RepJobs chan int64 SM *SM quit chan bool } 包含了workid和执行任务的id,上面的SM只是任务具体内容,这个和具体业务相关,大家自己编写自己的SM业务逻辑 然后定义工作池 type workerPool struct { workerChan chan *Worker workerList []*Wo

  • 基于Golang 高并发问题的解决方案

    Golang 高并发问题的解决 Golang在高并发问题上,由于协程的使用,相对于其他编程语言,已经有了很大的优势,即相同的配置上,Golang可以以更低的代价处理更多的线程,同样的线程数,占用更低的资源!及时这样,只是解决了一部分问题而已,因为在每个协程里,处理逻辑还是会有问题. 高并发时,还是要考虑服务器所能承受的最大压力,数据库读取时的io问题,连接数问题,带宽问题等等 研究了一下并发解决方案,在此记录一下 参考文章:Handling 1 Million Requests per Minu

  • 关于golang高并发的实现与注意事项说明

    一.并发的意义 并发的意义就是让 一个程序同时做多件事情,其目的只是为了能让程序同时做另一件事情而已,而不是为了让程序运行的更快(如果是多核处理器,而且任务可以分成相互独立的部分,那么并发确实可以让事情解决的更快). golang从语言级别上对并发提供了支持,而且在启动并发的方式上直接添加了语言级的关键字,不必非要按照固定的格式来定义线程函数,也不必因为启动线程的时候只能给线程函数传递一个参数而烦恼. 二.并发的启动 go的并发启动非常简单,几乎没有什么额外的准备工作,要并发的函数和一般的函数没

  • golang中的并发和并行

    golang中默认使用一个CPU,这时程序无法并发,只能是并发.因为始终只有一个CPU在运行. package main import ( "fmt" "runtime" ) //并发和并行 var quit chan int = make(chan int) func loop() { for i := 0; i < 100; i++ { //为了观察,跑多些 fmt.Printf("%d ", i) } quit <- 0 } f

  • 一文带你了解Golang中的并发性

    目录 什么是并发性,为什么它很重要 并发性与平行性 Goroutines, the worker Mortys Channels, the green portal 总结 并发是一个很酷的话题,一旦你掌握了它,就会成为一笔巨大的财富.说实话,我一开始很害怕写这篇文章,因为我自己直到最近才对并发性不太适应.我已经掌握了基础知识,所以我想帮助其他初学者学习Go的并发性.这是众多并发性教程中的第一篇,请继续关注更多的教程. 什么是并发性,为什么它很重要 并发是指在同一时间运行多个事物的能力.你的电脑有

  • 解析golang中的并发安全和锁问题

    1. 并发安全 package main import ( "fmt" "sync" ) var ( sum int wg sync.WaitGroup ) func test() { for i := 0; i < 5000000; i++ { sum += 1 } wg.Done() } func main() { // 并发和安全锁 wg.Add(2) go test() go test() wg.Wait() fmt.Println(sum) } 上面

  • 详解Golang 中的并发限制与超时控制

    前言 上回在 用 Go 写一个轻量级的 ssh 批量操作工具里提及过,我们做 Golang 并发的时候要对并发进行限制,对 goroutine 的执行要有超时控制.那会没有细说,这里展开讨论一下. 以下示例代码全部可以直接在 The Go Playground上运行测试: 并发 我们先来跑一个简单的并发看看 package main import ( "fmt" "time" ) func run(task_id, sleeptime int, ch chan st

  • 示例剖析golang中的CSP并发模型

    目录 1. 相关概念: 2. CSP (通信顺序进程) 3. channel:同步&传递消息 4. goroutine:实际并发执行的实体 5. golang调度器 1. 相关概念: 用户态:当一个进程在执行用户自己的代码时处于用户运行态(用户态) 内核态:当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态),引入内核态防止用户态的程序随意的操作内核地址空间,具有一定的安全保护作用.这种保护模式是通过内存页表操作等机制,保证进程间的地址空间不会相互冲突,一个进程的操作不会修改另一个

  • Golang中goroutine和channel使用介绍深入分析

    目录 1.goroutine-看一个需求 2.进程和线程介绍 3.并发和并行 4.Go协程和Go主线程 5.设置Golang运行的CPU数 6.channel(管道)看需求 1.goroutine-看一个需求 需求:要求统计1-900000000的数字中,那些是素数? 分析: 传统方法,就是使用一个循环,循环的判断各个数是不是素数. 使用并发或并行的方式,将统计素数的任务分配给多个goroutine去完成,这时就会使用到goroutine. 2.进程和线程介绍 进程就是程序在操作系统中的一次执行

  • Python中的并发编程实例

    一.简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执行,这个控制流被称为该进程的主线程.在任何给定的时刻,一个程序只做一件事情. 一个程序可以通过Python库函数中的os或subprocess模块创建新进程(例如os.fork()或是subprocess.Popen()).然而,这些被称为子进程的进程却是独立运行的,它们有各自独立的系统状态以及

  • .NET Core 中的并发编程

    并发编程 - 异步 vs. 多线程代码 并行编程是一个广泛的术语,我们应该通过观察异步方法和实际的多线程之间的差异展开探讨. 尽管 .NET Core 使用了任务来表达同样的概念,一个关键的差异是内部处理的不同. 调用线程在做其他事情时,异步方法在后台运行.这意味着这些方法是 I/O 密集型的,即他们大部分时间用于输入和输出操作,例如文件或网络访问. 只要有可能,使用异步 I/O 方法代替同步操作很有意义.相同的时间,调用线程可以在处理桌面应用程序中的用户交互或处理服务器应用程序中的同时处理其他

  • 深入了解Java语言中的并发性选项有何不同

    前言 Java™ 工程师在努力让并发性容易为开发人员所用.尽管做了不少的改进,但并发性仍然是 Java 平台的一个复杂.容易出错的部分.一部分复杂之处在于理解语言本身中的并发性的低级抽象,这些抽象在您的代码中填满了同步的代码块.另一个复杂之处来自一些新库,比如 fork/join,这些库在某些场景中非常有用,但在其他场景中收效甚微.了解容易混乱的大量低级选项需要专业经验和时间. 脱离 Java 语言的优势之一是,能够改善和简化并发性等区域.每种 Java 下一代语言都为此问题提供了独特的答案,利

  • 在Golang中使用Redis的方法示例

    周五上班的主要任务是在公司老平台上用redis处理一个队列问题,顺便复习了一下redis操作的基础知识,回来后就想着在自己的博客demo里,用redis来优化一些使用场景,学习一下golang开发下redis的使用. Redis简单介绍 简介 关于Redis的讨论,其实在现在的后台开发中已经是个老生常谈的问题,基本上也是后端开发面试的基本考察点.其中 Redis的背景介绍和细节说明在这里就不赘述.不管怎么介绍,核心在于Redis是一个基于内存的key-value的多数据结构存储,并可以提供持久化

随机推荐