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稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...
随机推荐
- HDU 4489 The King’s Ups and Downs
http://acm.hdu.edu.cn/showproblem.php?pid=4489 题意:有n个身高不同的人,计算高低或低高交错排列的方法数. 思路:可以按照身高顺序依次插进去. d[i][ ...
- XML_CPP_ZC_libXml2
1.错误信息: /* * Use the following function to reset the two global variables * xmlGenericError and xmlG ...
- QWebEngineView_CssVariables
1.测试代码,参考网址:http://blog.sina.com.cn/s/blog_1508519340102wgq0.html 2.测试下来,结果: 2.1.Qt5.6开始,没有 WebKit了. ...
- 如何借助 OVN 来提高 OVS 在云计算环境中的性能
众所周知,OpenvSwitch 以其丰富的功能和不错的性能,已经成为 Openstack 部署中最受欢迎的虚拟交换机.由于 Openstack Neutron 的架构引入了一些性能问题,比如 neu ...
- [java]java String.split()函数的用法分析
转自:http://swiftlet.net/archives/709 一.在java.lang包中有String.split()方法的原型是: public String[] split(Strin ...
- Libpacp 深度剖析
Libpacp 深度剖析 1. Libpacp 的工作原理 Libpcap的工作原理可以描述为,当一个数据包到达网卡时,通过网络分接口(即旁路机制)将数据包发给BPF过滤器,匹配通过的数据包可以被 ...
- FastJson/spring boot: json输出方法二
1.引入FastJson依赖包 <!-- FastJson --> <dependency> <groupId>com.alibaba</groupId> ...
- log4j日志文件配置
### set log levels ### ### debug (打印代码中logger.debug(xx)的信息)> info(打印代码中logger.info(xx)的信息) log4j. ...
- torchnet+VGG16计算patch之间相似度
torchnet+VGG16计算patch之间相似度 torch VGG16 similarity 本来打算使用VGG实现siamese CNN的,但是没想明白怎么使用torchnet对模型进行微调. ...
- UVALive-3887 Slim Span (kruskal)
题目大意:定义无向图生成树的最大边与最小边的差为苗条度,找出苗条度最小的生成树的苗条度. 题目分析:先将所有边按权值从小到大排序,在连续区间[L,R]中的边如果能构成一棵生成树,那么这棵树一定有最小的 ...