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稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...
随机推荐
- codeforces 9 div2 C.Hexadecimal's Numbers 暴力打表
C. Hexadecimal's Numbers time limit per test 1 second memory limit per test 64 megabytes input stand ...
- append 注意事项
>>> t1 = [, ] >>> t2 = t1.append() >>> t1 [, , ] >>> t2 None
- 使用 while 循环
与 for 循环不同,while 循环会一直运行,直到给定条件不满足为止.例如,下面的 while 循环从 x=0 开始.每次循环都会检查 x<=10 是否成立.如果成立,就执行循环内部的表达式 ...
- 利用Minhash和LSH寻找相似的集合(转)
问题背景 给出N个集合,找到相似的集合对,如何实现呢?直观的方法是比较任意两个集合.那么可以十分精确的找到每一对相似的集合,但是时间复杂度是O(n2).当N比较小时,比如K级,此算法可以在接受的时间范 ...
- jq对象和DOM对象的互换
var oJq; //JQ对象 var oDom; //dom对象 oDom = oJq[index]; // JQ对象转化为oDom对象 oJq = $(oDom); //DOM对象 ...
- git 使用和安装
http://www.git-scm.com/download/ http://www.git-scm.com/download/win http://www.git-scm.com/download ...
- Qt Creator下应用CMake项目调试mex文件
网上可以找到很多应用Visual Studio编写.编译mex文件,并与MATLAB联合调试的文章.但这只限于Win平台,网上许多源码都是.mexa64的文件,它们的作者是怎么调试的呢?这里我介绍一下 ...
- UVA-1610 Party Games (构造)
题目大意:给出一系列字符串,构造出一个字符串大于等于其中的一半,小于另一半. 题目分析:取大小为中间的两个a,b(a<b).实际上就是找出第一个小于b的同时大于等于a的字符串,直接构造即可.要注 ...
- UVA-1149 Bin Packing (贪心)
题目大意:给定n个物品的重量,无限个容量为m的箱子,每个箱子最多装两个物品,要把所有的物品都装下,最少需要多少个箱子. 题目分析:贪心策略:每次将最重和最轻的两个物品放到一个箱子里,如果装不下,则将最 ...
- haskell 常用 函数
在学习haskell 记录以下常用的函数 随时更新! span span :: (a -> Bool) -> [a] -> ([a], [a]) span, applied to ...