Go语言并发编程总结
转自:http://blog.csdn.net/yue7603835/article/details/44309409
import(
"fmt"
"sync"
"runtime"
)
var count int =;
func counter(lock * sync.Mutex){
lock.Lock()
count++
fmt.Println(count)
lock.Unlock()
}
func main(){
lock:=&sync.Mutex{}
for i:=;i<;i++{
//传递指针是为了防止 函数内的锁和 调用锁不一致
go counter(lock)
}
for{
lock.Lock()
c:=count
lock.Unlock()
///把时间片给别的goroutine 未来某个时刻运行该routine
runtime.Gosched()
if c>={
fmt.Println("goroutine end")
break
}
}
}
package main
import "fmt"
func Count(ch chan int) {
ch <-
fmt.Println("Counting")
}
func main() {
chs := make([]chan int, )
for i := ; i < ; i++ {
chs[i] = make(chan int)
go Count(chs[i])
fmt.Println("Count",i)
}
for i, ch := range chs {
<-ch
fmt.Println("Counting",i)
}
}
select {
case <-chan1: // 如果chan1成功读到数据,则进行该case处理语句
case chan2 <- : // 如果成功向chan2写入数据,则进行该case处理语句
default: // 如果上面都没有成功,则进入default处理流程
}
for i := range c {
fmt.Println("Received:", i)
}
package main
import "fmt"
import "time"
func Producer (queue chan<- int){
for i:= ; i < ; i++ {
queue <- i
}
}
func Consumer( queue <-chan int){
for i :=; i < ; i++{
v := <- queue
fmt.Println("receive:", v)
}
}
func main(){
queue := make(chan int, )
go Producer(queue)
go Consumer(queue)
time.Sleep(1e9) //让Producer与Consumer完成
}
make(c1 chan int) 创建的是 同步channel ...读写完全对应
make(c1 chan int ,) 闯进带缓冲的通道 上来可以写10次
package main
import "fmt"
import "time"
func main(){
ch := make(chan int, )
for {
///不停向channel中写入 0 或者1
select {
case ch <- :
case ch <- :
}
//从通道中取出数据
i := <-ch
fmt.Println("Value received:",i)
time.Sleep(1e8)
}
}
c := make(chan int, )
for i := range c {
fmt.Println("Received:", i)
}
////////////////////////////////////////下面是测试代码////////////////////////////////////
package main
import "fmt"
import "time"
func A(c chan int){
for i:=;i<;i++{
c<- i
}
}
func B(c chan int){
for val:=range c {
fmt.Println("Value:",val)
}
}
func main(){
chs:=make(chan int,)
//只要有通道操作一定要放到goroutine中否则 会堵塞当前的主线程 并且导致程序退出
//对于同步通道 或者带缓冲的通道 一定要封装成函数 使用 goroutine 包装
go A(chs)
go B(chs)
time.Sleep(1e9)
}
import "os"
func main() {
for i:=; i<; i++ {
go func() {
for {
b:=make([]byte, )
os.Stdin.Read(b) // will block
}
}()
}
select{}
}
type PipeData struct {
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是一个原生类型,因此不仅 支持被传递,还支持类型转换。只有在介绍了单向channel的概念后,读者才会明白类型转换对于
channel的意义:就是在单向channel和双向channel之间进行转换。
示例如下:
ch4 := make(chan int)
ch5 := <-chan int(ch4) // ch5就是一个单向的读取channel
ch6 := chan<- int(ch4) // ch6 是一个单向的写入channel
func Parse(ch <-chan int) {
for value := range ch {
fmt.Println("Parsing value", value)
}
}
package main
import "fmt"
import "time"
//接受一个参数 是只允许读取通道 除非直接强制转换 要么你只能从channel中读取数据
func sCh(ch <-chan int){
for val:= range ch {
fmt.Println(val)
}
}
func main(){
//创建一个带100缓冲的通道 可以直接写入 而不会导致 主线程堵塞
dch:=make(chan int,)
for i:=;i<;i++{
dch<- i
}
//传递进去 只读通道
go sCh(dch)
time.Sleep(1e9)
}
close(ch)
x, ok := <-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 <-
// 发信号告诉任务管理者我已经计算完成了
}
const NCPU =
// 假设总共有16核
func (v Vector) DoAll(u Vector) {
c := make(chan int, NCPU) // 用于接收每个CPU的任务完成信号
for i := ; i < NCPU; i++ {
go v.DoSome(i*len(v)/NCPU, (i+)*len(v)/NCPU, u, c)
}
// 等待所有CPU的任务完成
for i := ; i < NCPU; i++ {
<-c // 获取到一个数据,表示一个CPU计算完成了
}
// 到这里表示所有计算已经结束
}
runtime.GOMAXPROCS()
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()
}
var done bool = false
func setup() {
a = "hello, world"
done = true
}
func doprint() {
if !done {
setup()
}
print(a)
}
func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool)
Go语言并发编程总结的更多相关文章
- Go语言 并发编程
Go语言 并发编程 作者:Eric 微信:loveoracle11g 1.创建goroutine // 并行 是两个队列同时使用两台咖啡机 // 并发 是两个队列交替使用一台咖啡机 package m ...
- 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
2007年诞生的Go语言,凭借其近C的执行性能和近解析型语言的开发效率,以及近乎完美的编译速度,席卷全球.Go语言相关书籍也如雨后春笋般涌现,前不久,一本名为<Go语言并发之道>的书籍被翻 ...
- go语言并发编程
引言 说到go语言最厉害的是什么就不得不提到并发,并发是什么?,与并发相关的并行又是什么? 并发:同一时间段内执行多个任务 并行:同一时刻执行多个任务 进程.线程与协程 进程: 进程是具有一定独立功能 ...
- Go语言并发编程示例 分享(含有源代码)
GO语言并发示例分享: ppt http://files.cnblogs.com/files/yuhan-TB/GO%E8%AF%AD%E8%A8%80.pptx 代码, 实际就是<<Go ...
- Python3 与 C# 并发编程之~ 线程篇
2.线程篇¶ 在线预览:https://github.lesschina.com/python/base/concurrency/3.并发编程-线程篇.html 示例代码:https://gith ...
- 11 go并发编程-上
其他编程语言并发编程的效果 并发编程可以让开发者实现并行的算法以及编写充分利用多核处理器和多核性能的程序.在当前大部分主流的编程语言里,如C,C++,java等,编写维护和调试并发程序相比单线程程序而 ...
- golang:并发编程总结
并行和并发 并发编程是指在一台处理器上"同时"处理多个任务. 宏观并发:在一段时间内,有多个程序在同时运行. 微观并发:在同一时刻只能有一条指令执行,但多个程序指令被快速的轮换执行 ...
- 《Go并发编程实战》读书笔记-初识Go语言
<Go并发编程实战>读书笔记-初识Go语言 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在讲解怎样用Go语言之前,我们先介绍Go语言的特性,基础概念和标准命令. 一. ...
- c++ 11开始语言本身和标准库支持并发编程
c++ 11开始语言本身和标准库支持并发编程,意味着真正要到编译器从语言和标准库层面开始稳定,估计得到17标准出来.14稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...
随机推荐
- mygene 3.0.0
MyGene.Info provides simple-to-use REST web services to query/retrieve gene annotation data. It’s de ...
- python 清空列表
# lst = ["篮球","排球","乒乓球","足球","电子竞技","台球" ...
- 使用 if 语句
与很多编程语言一样,if 表达式用来处理逻辑条件.在 R 中,逻辑条件通常表达为某个表达式返回的单值逻辑向量.例如,我们可以写一个简单的函数 check_positive,如果输入一个正数则返回 1, ...
- Factory Method(工厂方法)
Factory Method(工厂方法) 意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性: 当一个类不知道它所必须创 ...
- Java 数组如何转成List集合
问题描述:对于给定的如下数组,如何转换成List集合? String[] array = {"a","b","c"}; 参考stackove ...
- 利用JS将页面中包含“一个”字段值的元素改为红色
document.body.innerHTML = document.body.innerHTML.replace(/一个/ig,"<span style='color: red;'& ...
- ✅问题:Rails.ajax自定义请求
chatroom.coffee中的js代码: document.addEventListener 'turbolinks:load', -> document.getElementById(&q ...
- 017PHP基础知识——流程控制语句(五)
<?php /** * break;退出循环: * 语法结构:break int;可以指定跳过几级循环: * while do_while for foreach switch */ /*$i= ...
- Python3.5 源码安装 Ubuntu16.04环境
安装源码编译所需的各种依赖库:(Ubuntu16.04环境下) sudo apt-get install zlib1g-dev libbz2-dev libssl-dev libncurses5-de ...
- rabbitmq学习(四):利用rabbitmq实现远程rpc调用
一.rabbitmq实现rpc调用的原理 ·rabbitmq实现rpc的原理是:客户端向一个队列中发送消息,并注册一个回调的队列用于接收服务端返回的消息,该消息需要声明一个叫做correaltionI ...