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 0
原创粉丝点击