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

Go语言实现并发(协程)

用go命令来执行协程

普通程序

package main

import "fmt"
import "time"

func go_worker(name string){
	for i:=0; i<5; i++{
		fmt.Println("我是一个go协程,我的名字是 ",name)
		time.Sleep(1 * time.Second)
	}
	fmt.Println(name,"执行完毕")
}

func main(){
	go_worker("小黑")

}

 

用协程执行

package main

import "fmt"
import "time"

func go_worker(name string){
	for i:=0; i<5; i++{
		fmt.Println("我是一个go协程,我的名字是 ",name)
		time.Sleep(1 * time.Second)
	}
	fmt.Println(name,"执行完毕")
}

func main(){
	//开辟一个go协程
	go go_worker("小黑")
	//开辟一个go协程
	go go_worker("小白")

	for i:=0; i<10; i++{
		fmt.Println("我是main")
		time.Sleep(1 * time.Second)
	}
}

 

channel实现协程通信

 

      c := make(chan int)

你想传递整型就int,想传递字符串就string

package main

import "fmt"

func worker(c chan int) {
	//从channel c中得到数据
	num := <-c
	fmt.Println("得到了管道中的数据 ", num)
}

func main() {
	//创建⼀个channel
	c := make(chan int)
	
	//开辟一个协程,去执行worker函数
	go worker(c)

	//main向channel c中写数据
	c <- 1

	fmt.Println("我是main")
}

 

等待组sync.WaitGroup

       多线程编程中,经常会遇到这样的一种场景:main函数中为了等待其他线程执行完,在return之前都要执行sleep以争取更多的时间给其他线程执行.

      主线程为了等待goroutine都运行完毕,不得不在程序的末尾使用time.Sleep() 来睡眠一段时间,等待其他线程充分运行。对于简单的代码,100个for循环可以在1秒之内运行完毕,time.Sleep() 也可以达到想要的效果。但是对于实际场景来说,大多无法预知for循环内代码运行时间的长短,因此1秒可能是不够的。所以睡眠也就达不到我们想要的效果。

 

      WaitGroup(等待组)就是用来解决这种问题的,它主要用于同步多个协程间的状态(例如等待所有协程都执行完)。

      在WaitGroup 对象实现中,内部有一个计数器,最初从0开始,它有三个方法:

  • Add():计数器加一
  • Done():计数器减一
  • Wait():等待计数器清零

 

执行Wait方法的函数在等待组内部计数器不为0的时候回阻塞,一旦计数器为0了,程序就会继续往下执行。

 

func main() {
    wg := sync.WaitGroup{}
    wg.Add(100)
    for i := 0; i < 100; i++ {
        go func(i int) {
            fmt.Println(i)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

 

相关文章:

  • 汇编语言相关知识
  • 面向对象的意义
  • 文本大数据挖掘项目(Go语言)
  • Python网络编程
  • CUDA与cuDNN
  • AI中的搜索(一)——启发式搜索 ((贪婪)最佳优先搜索 (Greedy)Best-First Search、A* 、迭代加深搜索 和 IDA* )
  • AI中的搜索(二)——对抗搜索(最小最大搜索Minimax、Alpha-Beta剪枝搜索、蒙特卡洛树搜索MCTS)
  • Web1.0 与 Web2.0 时代
  • HTTP服务器开发项目(Python)
  • IO多路复用(Select,Poll,Epoll)
  • Reactjs jsx
  • HTTP服务器开发项目之基础知识——传输层TCP协议 应用层HTTP协议(http请求报文应答报文详解)
  • 自制简易浏览器(Python)
  • 编译安装linux内核
  • Python中的*args,**kwargs(可变参数)(传参)
  • 自己简单写的 事件订阅机制
  • HTML中设置input等文本框为不可操作
  • js中forEach回调同异步问题
  • php ci框架整合银盛支付
  • Service Worker
  • Vue ES6 Jade Scss Webpack Gulp
  • vue的全局变量和全局拦截请求器
  • Windows Containers 大冒险: 容器网络
  • 阿里云应用高可用服务公测发布
  • 分布式任务队列Celery
  • 规范化安全开发 KOA 手脚架
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 前端路由实现-history
  • 线上 python http server profile 实践
  • k8s使用glusterfs实现动态持久化存储
  • 带你开发类似Pokemon Go的AR游戏
  • #define
  • #pragma预处理命令
  • #控制台大学课堂点名问题_课堂随机点名
  • (ibm)Java 语言的 XPath API
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (办公)springboot配置aop处理请求.
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (一) springboot详细介绍
  • (转)程序员技术练级攻略
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET 表达式计算:Expression Evaluator
  • .Net中的设计模式——Factory Method模式
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • @Data注解的作用
  • []常用AT命令解释()
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [APIO2012] 派遣 dispatching
  • [BT]BUUCTF刷题第8天(3.26)
  • [C#]使用DlibDotNet人脸检测人脸68特征点识别人脸5特征点识别人脸对齐人脸比对FaceMesh
  • [C/C++] -- 二叉树
  • [CakePHP] 在Controller中使用Helper
  • [HTML]HTML5实现可编辑表格