Go并发编程(四)
多进程
多线程基于回调的非阻塞/异步IO协程
协程
goroutine
package main
import"fmt"
func Add(x, y int){
z := x + y
fmt.Println(z)
}
func main(){
for i :=0; i <10; i++{
go Add(i, i)
}
}
var count int
func 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 := count
lock.Unlock()
runtime.Gosched()
if c >10{
break
}
}
}
channel
channel是Go语言在语言级别提供的goroutine间的通信方式。
//声明一个chan
varch chan int
var mch map[string]chan bool
//声明并初始化一个int类型的chan
chan1 := make(chan int,1)
//将一个数据写入channel中
chan1 <-1
getchan1 :=<-chan1
chan1 := make(chan int,1)
//将1写入channel中
chan1 <-1
//将一个数据从channel中读取到getchan1中
getchan1 :=<-chan1
fmt.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 :=<-ch
fmt.Println("Value received:", i)
}
//创建一个带缓冲的channel
c := 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 int
handler func(int)int
next 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和一个单向写channel
ch4 := make(chan int)
ch5 :=<-chan int(ch4)// ch5就是一个单向的读取channel
ch6 := 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.Mutex
func foo(){
l.Lock()
defer l.Unlock()
//...
}
全局唯一性操作
var a string
var once sync.Once
func 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开发(27) 看看我的手机里都有什么传感器
想看看我的HTC ONE x 具有什么传感器.写个代码RUN一下. 代码很简单,直接贴了 package zyf.demo.sensordemo; import java.util.List; imp ...
- MFC宏
1,DECLARE_MESSAGE_MAP:在头文件中声明源文件中所含有的消息映射 2,BEGIN_MESSAGE_MAP:标记源文件消息映射的开始 3,END_MESSAGE_MA:标记源文件消息映 ...
- 关于socket的知识总结
简单点说: 阻塞就是干不完不准回来, 非组赛就是你先干,我现看看有其他事没有,完了告诉我一声 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系 ...
- install Mac OS on Vmware
本文将用详尽的图文介绍如何在虚拟机中安装运行Mac OS X,只要严格地按照本教程一步步操作,即使不了解苹果电脑的读者,也能顺利地安装并运行Mac OS X. 一.准备工作 VMWare 12 Pro ...
- USB2.0学习笔记连载(十八):keil实现寄存器的配置及相关函数讲解(二)
其实之前也有提及过,Cypress公司提供的官方文件和应用手册真的可以解决很多问题.做的也很人性化,操作也及其简单,几乎只要在 TD_int()里面配置一些常用的参数即可,其他都可以不用操作. 作为一 ...
- 如何能够通过代码来重启Android手机?
String cmd = "su -c reboot";//让手机从启 try { Runtime.getRuntime().exec(cmd); } catch (IOExcep ...
- mxnet img2rec的使用,生成数据文件
建立文件夹 制作lst文件,即生成train.lst文件python im2rec.py ./mxrec/train ./mxdata --list --recursive train.lst文件格式 ...
- MFC绘图基础——上机操作步骤
一.上机之前的介绍 软件环境:VC++6.0 目的:熟悉基本的MFC框架搭建和了解界面 二.MFC上机操作步骤 1,在Windows桌面上运行VC++6.0. 2,新建项目工程文件. 3,在MFC 应 ...
- e566. 关闭的时候关闭程序
By default, when the close button on a frame is clicked, nothing happens. This example shows how to ...
- java web 过滤器跟拦截器的区别和使用
注:文章整理自知乎大牛以及百度网友(电脑网络分类达人 吕明),特此感谢! 一.过滤器 1.什么是过滤器? 过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上.过滤器可附加到一个 ...