Go语言学习笔记2/2
来源:互联网 发布:中山大学图书馆 知乎 编辑:程序博客网 时间:2024/04/30 16:20
chap04 并发编程
1.Go语言支持语言级别轻量级别线程,称之为goroutine,由Go语言运行时runtime管理。如下多线程实例:
package main
import (
"fmt";
"sync";
"runtime"
)
var counter int = 0
func Count(lock *sync.Mutex){
lock.Lock()
counter++
fmt.Println(counter)
lock.Unlock()
}
func main(){
lock:=&sync.Mutex{}
for i:=0;i<10;i++ {
go Count(lock)
}
for {
lock.Lock()
c:=counter
lock.Unlock()
runtime.Gosched() //用于让cpu让出时间片
if c>=10 {
break
}
}
}
2.Go语言共享数据理念:不要通过共享内存来通信,而应该通过通信来共享内存。
3.channel是go语言goroutine间的通信方式。可以使用channel在不同的goroutine线程之间传递消息。channel是类型相关的。
定义:var chanName chan type ,初始化:chanName := make(chan type)。
写入:chanName <- value,读取:value := <- chanName。读取都会导致程序阻塞等待。
package main
import "fmt"
import "time"
func Count(ch chan int){
ch <- 1
fmt.Println(time.Now().UnixNano())
}
func main(){
chs := make([]chan int,10)
for i:=0;i<10;i++{
chs[i] = make (chan int)
go Count(chs[i])
}
for _,ch := range(chs) {
<-ch
fmt.Println("--------")
}
}
输出:
1470927062503429479
--------
4.select用于处理异步io,类似于switch,但是case的条件必须是io操作,没有判断条件。select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。
package main
import "fmt"
func main(){
ch := make(chan int,1)
for {
select {
case ch <- 0:
case ch <- 1:
}
i:=<-ch
fmt.Println("Value received",i)
}
}
需要确保执行时有一个case可以执行,否则死锁:fatal error: all goroutines are asleep - deadlock!
package main
import "fmt"
func main(){
ch := make(chan int,1)
for {
select {
case <-ch :
}
fmt.Println("Value received")
}
}
5.缓冲机制:设置缓冲区,缓冲区写满后才阻塞写。ch:=make(chan int,1024)
6.利用channel处理超时:
package main
import "fmt"
import "time"
func main(){
timeout := make(chan bool,1)
go func(){
time.Sleep(time.Second)
timeout<-true
}()
var ch chan int
select {
case <- ch :
case <- timeout:
fmt.Println("TimeOut...")
}
}
7.单项channel:
正常:var ch chan int
单项写:var ch chan<- int
单项读:var ch <-chan int
8.runtime.GOMAXPROCS(N)设置N个cpu参与到运算。runtime.Sched()释放时间片。
9.同步锁:syncMutex。读写锁:sync.RWMutex。
10.全局唯一操作:sync.Once
package main
import "fmt"
import "sync"
var once sync.Once
func hi() {
fmt.Print("hi")
}
func main(){
for i:=0;i<10;i++ {
fmt.Println("Round",i)
once.Do(hi)
}
}
1.Go语言支持语言级别轻量级别线程,称之为goroutine,由Go语言运行时runtime管理。如下多线程实例:
package main
import (
"fmt";
"sync";
"runtime"
)
var counter int = 0
func Count(lock *sync.Mutex){
lock.Lock()
counter++
fmt.Println(counter)
lock.Unlock()
}
func main(){
lock:=&sync.Mutex{}
for i:=0;i<10;i++ {
go Count(lock)
}
for {
lock.Lock()
c:=counter
lock.Unlock()
runtime.Gosched() //用于让cpu让出时间片
if c>=10 {
break
}
}
}
2.Go语言共享数据理念:不要通过共享内存来通信,而应该通过通信来共享内存。
3.channel是go语言goroutine间的通信方式。可以使用channel在不同的goroutine线程之间传递消息。channel是类型相关的。
定义:var chanName chan type ,初始化:chanName := make(chan type)。
写入:chanName <- value,读取:value := <- chanName。读取都会导致程序阻塞等待。
package main
import "fmt"
import "time"
func Count(ch chan int){
ch <- 1
fmt.Println(time.Now().UnixNano())
}
func main(){
chs := make([]chan int,10)
for i:=0;i<10;i++{
chs[i] = make (chan int)
go Count(chs[i])
}
for _,ch := range(chs) {
<-ch
fmt.Println("--------")
}
}
输出:
1470927062503429479
--------
4.select用于处理异步io,类似于switch,但是case的条件必须是io操作,没有判断条件。select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。
package main
import "fmt"
func main(){
ch := make(chan int,1)
for {
select {
case ch <- 0:
case ch <- 1:
}
i:=<-ch
fmt.Println("Value received",i)
}
}
需要确保执行时有一个case可以执行,否则死锁:fatal error: all goroutines are asleep - deadlock!
package main
import "fmt"
func main(){
ch := make(chan int,1)
for {
select {
case <-ch :
}
fmt.Println("Value received")
}
}
5.缓冲机制:设置缓冲区,缓冲区写满后才阻塞写。ch:=make(chan int,1024)
6.利用channel处理超时:
package main
import "fmt"
import "time"
func main(){
timeout := make(chan bool,1)
go func(){
time.Sleep(time.Second)
timeout<-true
}()
var ch chan int
select {
case <- ch :
case <- timeout:
fmt.Println("TimeOut...")
}
}
7.单项channel:
正常:var ch chan int
单项写:var ch chan<- int
单项读:var ch <-chan int
8.runtime.GOMAXPROCS(N)设置N个cpu参与到运算。runtime.Sched()释放时间片。
9.同步锁:syncMutex。读写锁:sync.RWMutex。
10.全局唯一操作:sync.Once
package main
import "fmt"
import "sync"
var once sync.Once
func hi() {
fmt.Print("hi")
}
func main(){
for i:=0;i<10;i++ {
fmt.Println("Round",i)
once.Do(hi)
}
}
1 0
- Go语言学习笔记2
- Go语言学习笔记2/2
- Go语言学习笔记1/2
- Go语言基础语法学习笔记[2]
- Go语言学习笔记 -- 函数(2)
- go语言学习笔记(2) 简单结构
- Go语言学习笔记(2)-变量,指针
- go语言学习2
- Go语言学习笔记
- Go语言学习笔记
- go语言学习笔记
- Go语言学习笔记
- GO语言学习笔记
- Go语言学习笔记
- GO语言学习笔记
- Go语言学习笔记
- Go语言学习笔记
- Go语言学习笔记
- GPRS使用AT指令发短信拨号
- Android 跨进程接口回调
- mysql查询执行顺序
- 人工智能与深度学习最好的入门资源
- Redis深入之路(五)
- Go语言学习笔记2/2
- 数据结构-散列
- 程序猿的第一天
- datatalble总结(一)
- javascript-spilce()和slice()
- my学习OC--变量 数据类型
- Ubuntu Apache搭建modSecurity,创建自己的WAF
- 单元介绍二
- 脏读,不可重复读,幻读