Golang并发实践:goroutine and channel实现并发

发布于 2017-09-05 · 本文总共 1553 字 · 阅读大约需要 5 分钟

golang并发编程

golang有两种并发编程的风格:

1.使用goroutine和channel,支持CSP(Communicating Sequential Process); CSP是一种并发的模式,在不同的执行体(goroutine)之间传递值,但是变量本身局限于单一的执行体

2.共享内存

goroutine示例

package main

import (
        "time"
        "fmt"
)

func Fib()  {
        go spinner(100 * time.Millisecond)
        const n  = 45
        fibN := fib(n)
        fmt.Printf("\rFibonacci(%d) = %d\n", n , fibN)
}


func spinner(delay time.Duration){
        for {
                for _, r := range `-\|/`{
                        fmt.Printf("\r%c", r)
                        // fmt.Println(".", time.Now())
                        time.Sleep(delay)
                }
        }
}

func fib(x int)  int{

        if x < 2{
                return x
        }
        return fib(x-1) + fib(x-2)
}

func main(){
        Fib()
}

go run main.go Fibonacci(45) = 1134903170

main函数返回时,所有的goroutine都暴力地终结,然后程序退出;

goroutine示例:并发时钟服务器

实现一个顺序时钟服务,每秒一次的频率向客户端发送当前时间

package main

import (
        "log"
        "net"
        "io"
        "time"
)

func TcpTimer(){
        listener, err := net.Listen("tcp", "localhost:8003")
        if err != nil{
                log.Fatal(err.Error())
        }

        for {
                conn, err := listener.Accept()
                if err != nil{
                        log.Print(err.Error())
                        continue
                }
                handleConn(conn)
        }
}

func handleConn(conn net.Conn){
        defer conn.Close()
        for {
                _, err := io.WriteString(conn, time.Now().Format("15:04:05\n"))
                if err != nil{
                        return
                }
                time.Sleep(1 * time.Second)
        }

}
func main(){
        TcpTimer()
}

go build main.go ./main &

nc localhost 8003 18:27:39 18:27:40 18:27:41

使用go关键字支持并发:

for {
        conn, err := listener.Accept()
        if err != nil{
                log.Print(err.Error())
                continue
        }
        go handleConn(conn)
}

实现Golang版的netcat:

func NetCat()  {
        conn, err := net.Dial("tcp", "localhost:8003")
        if err != nil{
                log.Fatal(err)
        }
        defer conn.Close()

        MustCopy(os.Stdout, conn)
}

func MustCopy(dst io.Writer, src io.Reader){
        if _, err := io.Copy(dst, src);err != nil{
                log.Fatal(err)
        }
}

go run main.go 18:36:07 18:36:08 18:36:09 18:36:10

go版本

go version go1.13.6 darwin/amd64

refs

《The Go Programming Language》Alan A.A, Donovan & Brian W.Kernighan




本博客所有文章采用的授权方式为 自由转载-非商用-非衍生-保持署名 ,转载请务必注明出处,谢谢。
声明:
本博客欢迎转发,但请保留原作者信息!
博客地址:邱文奇(qiuwenqi)的博客;
内容系本人学习、研究和总结,如有雷同,实属荣幸!
阅读次数:

文章评论

comments powered by Disqus


章节列表