zoukankan      html  css  js  c++  java
  • go语言关于线程与通道channal

    在go语言中,封装了多线程的使用方法,使其变得简单易用。

    在这里说说自己一点体会,不正确的地方还是请各位大牛指正。

    关于go语言的并发机制,这很简单,在你要执行的函数前面加上go即可

    比如:

    package main

    import(
    "fmt" ) func main(){ go fmt.Println("1") fmt.Println("2") }

    好了 这样即可使用,但是这个程序运行的时候会出问题,你会发现1打印不出来,为啥?

    你问我为啥?

    这是因为在执行这个的时候,你可以想像,程序优先执行主线程,这时会打印出2,然后程序就退出了,这个时候程序还没来及打印并发下的1,就退出了所以你看不到!!

    那么怎么才能看到哪?

    加个延时,等到线程把事情搞完才退出就能看到了,就像这样

    package main
    
    import(
    
             "fmt"
    
    )
    func main(){
    
        go fmt.Println("1")
    
        fmt.Println("2")    
    
       time.Sleep(time.Second*1) }

    这样你就会发现,其实程序先打印2,在打印1,因为是主线程优先的,所以会出现这种状况(我猜的,管你信不信,好吧这是真的,你问谁都是这样给你说)

    不管怎么说,我就问你这个多线程学起来简单不简单?你觉得是CreateThread()爽,还是这个爽!

    下面说说通道channal

    这个哪,你就可以理解成多线程之间通信的一个通道。

    你问我怎么用这东西?

    ch:=make (chan int)

    chan是通道的关键字

    make那就是创建的意思

    int 那就是int类型的通道

    简单不简单,开心不开心?

    你开心的太早了,哈哈哈哈哈

    上面仅仅是说了基本的用法,这里还有点东西需要在详细的说下,不然你还是不懂怎么用chan搞事情!

    上面的

    ch := make(chan int)

    是创建一个无缓冲区的int类型的chan,具体什么叫无缓冲区,额,不知道怎么解释,以后再说吧

    ch :=make(<-chan int)

    这个是无缓冲区只读的ch

    ch:=make(chan<- int)

    无缓冲只写的 chan

    关于"<-"符号,在go的多线程中会经常碰到,你需要知道一点这个是做什么用的

    按照我的理解:

    ch<-

    这个意思是将数据写入ch

    <-ch这个意思是将数据从ch中读出来

    还是一个小例子说下相关的东西:

    package main
    import(
    
        "fmt"
    
    //    "time"
    )
    func main(){
    
        ch:=make(chan int)
        ch<-1
        go func (){
            <-ch
            fmt.Println("1")
        }()
        fmt.Println(":2")
    
    
    }

    运行之后会告诉你,死锁了,为什么会出现?他是无缓冲区,也就是赋值必须要进去取值。不然就是死锁

    package main
    import(
    
    	"fmt"
    
    //	"time"
    	"time"
    )
    func main(){
    
    	ch:=make(chan int,1)
    	ch<-1
    
    
    	go func (){
    		v:=<-ch
    		fmt.Println(v)
    	}()
    	fmt.Println(":2")
    	time.Sleep(time.Second*1)
    
    }
    

     这样试试看哪

    package main
    import(

    "fmt"

    // "time"
    "time"
    )
    func main(){

    ch:=make(chan int)



    go func (){
    v:=<-ch
    fmt.Println(v)
    }()
    ch<-1
    fmt.Println(":2")


    }

    或者这样,后面这个是无缓冲区的,这样的话,ch在赋值的时候被阻塞,知道gofunc给取走,这样打印出来的结果就是1,2

    生产消费者:

    import (

        "fmt"
        "time"
    )
    func produce(p chan<- int) {
        for i := 0; i < 10; i++ {
            p <- i
            fmt.Println("send:", i)
        }
    }
    func consumer(c <-chan int) {
        for i := 0; i < 10; i++ {
            v := <-c
            fmt.Println("receive:", v)
        }
    }
    func main() {
        ch := make(chan int)
        go produce(ch)
        go consumer(ch)
        time.Sleep(1 * time.Second)
    }

    这个例子,我觉得能够体现的更明显,无缓冲区意味着这就是同步的,也就是说只能是ch写入,取出,写入,取出,写入,取出这样走,无缓冲区必须保证一个写入,另一个取出,才能执行下一次

    再看看这个:

    import (

        "fmt"
        "time"
    )
    func produce(p chan<- int) {
        for i := 0; i < 10; i++ {
            p <- i
            fmt.Println("send:", i)
        }
    }
    func consumer(c <-chan int) {
        for i := 0; i < 10; i++ {
            v := <-c
            fmt.Println("receive:", v)
        }
    }
    func main() {
        ch := make(chan int, 10)
        go produce(ch)
        go consumer(ch)
        time.Sleep(1 * time.Second)
    }


    再来看看这个,这个有缓冲区的,啥意思?

    就是我有个容器,我可以一直往里面生产,知道这个被填满,也就是我可以一直往这个缓冲区塞东西,直到这10个被填满,我也可以一直读数据,也可以一下全部取出来。

    大概就是这么意思。

    参考文档:

    http://studygolang.com/articles/3311

  • 相关阅读:
    css3
    css3
    npm 安装包无法继续下载? 卡住
    tcp/ip协议中的SYN, ACK的数值变化
    【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)
    ES6 中 Symbol.split的用法
    Why does Typescript use the keyword “export” to make classes and interfaces public?
    es6中的import,export浏览器已经支持
    Understanding the JavaScript Engine—— two phase
    【转】js-ES6学习笔记-Symbol
  • 原文地址:https://www.cnblogs.com/fudong071234/p/6759567.html
Copyright © 2011-2022 走看看