Go并发编程(四)
多进程
多线程基于回调的非阻塞/异步IO协程
协程
goroutine
package mainimport"fmt"func Add(x, y int){z := x + yfmt.Println(z)}func main(){for i :=0; i <10; i++{go Add(i, i)}}
var count intfunc Count(lock*sync.Mutex){lock.Lock()count++fmt.Println(count)lock.Unlock()}func main(){lock:=&sync.Mutex{}for i :=0; i <10; i++{go Count(lock)}for{lock.Lock()c := countlock.Unlock()runtime.Gosched()if c >10{break}}}
channel
channel是Go语言在语言级别提供的goroutine间的通信方式。
//声明一个chanvarch chan intvar mch map[string]chan bool//声明并初始化一个int类型的chanchan1 := make(chan int,1)//将一个数据写入channel中chan1 <-1getchan1 :=<-chan1
chan1 := make(chan int,1)//将1写入channel中chan1 <-1//将一个数据从channel中读取到getchan1中getchan1 :=<-chan1fmt.Println(getchan1) //输出1
select
通过调用select()函数来监控一系列的文件句柄。一旦其中一个文件句柄发生了IO动作,该select()调用就会被返回
select{case<-chan1:// 如果chan1成功读到数据,则进行该case处理语句case chan2 <-1:// 如果成功向chan2写入数据,则进行该case处理语句default:// 如果上面都没有成功,则进入default处理流程}
ch := make(chan int,1)for{select{case ch <-0:case ch <-1:}i :=<-chfmt.Println("Value received:", i)}
//创建一个带缓冲的channelc := make(chan int,1024)
// 首先,我们实现并执行一个匿名的超时等待函数timeout := make(chan bool,1)go func(){time.Sleep(1e9)// 等待1秒钟timeout <-true}()// 然后我们把timeout这个channel利用起来select{case<-ch:// 从ch中读取到数据case<-timeout:// 一直没有从ch中读取到数据,但从timeout中读取到了数据}
channel的传递
type PipeDatastruct{value inthandler func(int)intnext chan int}
func handle(queue chan *PipeData){for data := range queue {data.next<- data.handler(data.value)}}
var ch1 chan int// ch1是一个正常的channel,不是单向的var ch2 chan<- float64// ch2是单向channel,只用于写float64数据var ch3 <-chan int// ch3是单向channel,只用于读取int数据
//单项channel初始化,ch4被转换为一个单项读channel和一个单向写channelch4 := make(chan int)ch5 :=<-chan int(ch4)// ch5就是一个单向的读取channelch6 := chan<-int(ch4)// ch6 是一个单向的写入channel
close(ch)
x, ok :=<-ch //返回值是false则表示ch已经被关闭。
多核并行化
type Vector[]float64// 分配给每个CPU的计算任务func (v Vector)DoSome(i, n int, u Vector, c chan int){for; i < n; i++{v[i]+= u.Op(v[i])}c <-1// 发信号告诉任务管理者我已经计算完成了}const NCPU =16// 假设总共有16核func (v Vector)DoAll(u Vector){c := make(chan int, NCPU)// 用于接收每个CPU的任务完成信号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 // 获取到一个数据,表示一个CPU计算完成了}// 到这里表示所有计算已经结束}
GOMAXPROCS只是个时间问题。
runtime.Gosched()
典型使用模式如下:
var l sync.Mutexfunc foo(){l.Lock()defer l.Unlock()//...}
全局唯一性操作
var a stringvar once sync.Oncefunc setup(){a ="hello, world"}func doprint(){once.Do(setup)print(a)}func twoprint(){go doprint()go doprint()}
once.Do()调用结束后才继续。
Go并发编程(四)的更多相关文章
- 【Java并发编程四】关卡
一.什么是关卡? 关卡类似于闭锁,它们都能阻塞一组线程,直到某些事件发生. 关卡和闭锁关键的不同在于,所有线程必须同时到达关卡点,才能继续处理.闭锁等待的是事件,关卡等待的是其他线程. 二.Cycli ...
- Java 并发编程(四):如何保证对象的线程安全性
01.前言 先让我吐一句肺腑之言吧,不说出来会憋出内伤的.<Java 并发编程实战>这本书太特么枯燥了,尽管它被奉为并发编程当中的经典之作,但我还是忍不住.因为第四章"对象的组合 ...
- 并发编程>>四种实现方式(三)
概述 1.继承Thread 2.实现Runable接口 3.实现Callable接口通过FutureTask包装器来创建Thread线程 4.通过Executor框架实现多线程的结构化,即线程池实现. ...
- Java并发编程 (四) 线程安全性
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.线程安全性-原子性-atomic-1 1.线程安全性 定义: 当某个线程访问某个类时,不管运行时环境 ...
- Java并发编程(四):并发容器(转)
解决并发情况下的容器线程安全问题的.给多线程环境准备一个线程安全的容器对象. 线程安全的容器对象: Vector, Hashtable.线程安全容器对象,都是使用 synchronized 方法实现的 ...
- 并发编程(四):ThreadLocal从源码分析总结到内存泄漏
一.目录 1.ThreadLocal是什么?有什么用? 2.ThreadLocal源码简要总结? 3.ThreadLocal为什么会导致内存泄漏? 二.ThreadLoc ...
- java并发编程的艺术——第四章总结
第四章并发编程基础 4.1线程简介 4.2启动与终止线程 4.3线程间通信 4.4线程应用实例 java语言是内置对多线程支持的. 为什么使用多线程: 首先线程是操作系统最小的调度单元,多核心.多个线 ...
- 并发编程(四):atomic
本篇博客我们主要讲述J.U.C包下的atomic包,在上篇博客"并发模拟"的最后,我们模拟高并发的情形时出现了线程安全问题,怎么解决呢?其实解决的办法有很多中,如直接在add()方 ...
- Python并发编程之线程消息通信机制任务协调(四)
大家好,并发编程 进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程 ...
随机推荐
- Android指南 - 样式和主题
本文翻译自:https://developer.android.com/guide/topics/ui/themes.html Style和theme词汇是专用术语,下文直接使用而不翻译. 样式和主题 ...
- 【程序练习】——ini格式转换为xml格式
;Configuration of http [http] doamin=www.mysite.com port= cgihome=/cgi-bin ;Configuration of db [d ...
- java 缩放算法 双线性插值,双三次插值
双线性插值的效果对于放大的图像而言较领域插值来得平滑,但是却使得图像变得模糊而且仍然会有一部分锯齿现象. 双三次插值更好比双线性插值更好. 图像缩放之双三次插值法 数字图像处理之双线性插值
- git设置HTTP代理
git设置HTTP代理 设置HTTP代理 如果公司使用代理,git就需要设置代理才能克隆远程仓库 执行下面两条语句 git config --global http.proxy 10.167.32.1 ...
- 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的 ...
- idea破解,idea激活,使用破解补丁无需注册码
dea激活,JetBrain旗下软件激活 前言 idea激活有多种方式,网上较多的是使用注册码或者填License server网址,目前(2017年8月19日)使用注册码的方式,亲测可用的只有lan ...
- Python之生成二面体群元素
from sympy.combinatorics.named_groups import DihedralGroup from collections import Counter n = 12 G ...
- tornado 添加请求头进行允许跨域
什么是跨域? 这个例子是csdn找的, 声明下哈 什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制. 所谓同源是指,域名,协议,端口均相同, ...
- Unity Package Manager Error的解决方案
问题来源 启动Unity时显示 fail to start Unity Package Manager,软件环境为 Unity 2017.3.0f3. 解决方案 根据网上所给的方案,我选择添加环境变量 ...
- Unity GUI(uGUI)使用心得与性能总结
Unity GUI(uGUI)使用心得与性能总结 作者 kingshijie 关注 2015.09.26 15:35 字数 3686 阅读 28031评论 10喜欢 49 背景和目的 小哈接触Unit ...