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稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...
随机推荐
- KMP&拓展KMP
KMP算法 说明 KMP算法是一种比较高效的字符串匹配算法,可以在线性时间内求出一个串在另一个串的所有匹配位置. 解析 详解KMP 设模板串是 \(pattern\) 令 \(next[i] = ma ...
- POJ 1122 FDNY to the Rescue!(最短路+路径输出)
http://poj.org/problem?id=1122 题意:给出地图并且给出终点和多个起点,输出从各个起点到终点的路径和时间. 思路: 因为有多个起点,所以这里反向建图,这样就相当于把终点变成 ...
- UVa 10294 项链和手镯(polya)
https://vjudge.net/problem/UVA-10294 题意: 手镯可以翻转,但项链不可以.输入n和t,输出用t种颜色的n颗珠子能制作成的项链和手镯的个数. 思路: 经典等价类计数问 ...
- zookeeper和Eureka对CAP理论的支持
著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性).A(可用性)和P(分区容错性).由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡.在此Zookeeper保证 ...
- 设计点滴&css效果点滴
走向设计师的第一步, 做一个自由的设计师. 优秀的移动端设计的:http://www.cnblogs.com/coding4/p/6842849.html 一些好的设计图片的收藏,一些好的设计理念,一 ...
- HDU-3853-期望/dp/坑
LOOPS Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others)Total Sub ...
- MySQL中视图和普通表的区别
1.视图是数据库数据的特定子集.可以禁止所有用户访问数据库表,而要求用户只能通过视图操作数据,这种方法可以保护用户和应用程序不受某些数据库修改的影响. 2.视图是抽象的,他在使用时,从表里提取出数据, ...
- hell 1>&2 2>&1 &>filename重定向的含义和区别
当初在shell中, 看到">&1"和">&2"始终不明白什么意思.经过在网上的搜索得以解惑.其实这是两种输出. 一.linux重定 ...
- Git标签(版本)管理
列出当前所有的标签 git tag 可以搜索特定的标签,例如你只想看稳定版相关的 git tag -l "*.stable" 给当前commit打标签(设定版本) gi ...
- 如何在.Net的MySqlCommand里面使用MySql用户自定义变量?
Mysql使用@符号代表变量,但C#也恰好使用@代表用户自定义变量,这样两者就会正好冲突了. SELECT () AS rowId, u.*, r.RoleName FROM userinfo u L ...