• go 语言 并发,并行,信道


    go语言

      并发

      并行

      信道

    package main
    
    import (
        "fmt"
        "time"
    )
    补充:
    //并发:看上去在同一时间同时执行,实际是切换执行利用时间片轮转法,同一个CPU进行切换执行
    // 并行:是在真正的同一时间两个程序同时进行吗,这个是在多核cpu情况下,同一时刻,两个事情同时进行
    //进程:进程是程序执行的最小单位,例如qq进程,迅雷进程,
    //   线程: 例如迅雷进程中,有上传,下载,上传就是一个线程,下载就是另一个线程
    //   协程:当线程碰到io操作时,就会一直停在那里,这个线程就一直处于浪费状态,此时我可以让这个线程转而去做其他的事,
    //       此时,就不是操作系统控制,而是由程序去控制,所以有genevt这个第三方模块,自动实现io切换,这就是单线程下实现并发即协程
    // node.js 本身只能在游览器中去执行,于是写了一个引擎,让代码跑在这个引擎上(类似于解释器)就可以跑在服务端上
    // 虽然js是一个解释型语言,但是node.js 使用了一个事件驱动,非阻塞i/o模型,运行特别快,碰到io就切
    // python 的async/await 协程  http请求用asyncio  异步框架sanic
    // python 中要想速度高,就得使用异步编程,异步框架
    
    
    //go中用关键字go即可,go语言并发性能高,go协程
    // go协程原理:go语言一旦跑起来,会在内部建一个很大的线程池,在线程池中go自己写好了算法,自己去调度,遇到io自己去切,自己去执行任务
    
    func test()  {
        fmt.Println("hello go")
    }
    //协程之间如何进行数据通信,就用信道
    func main()  {
        //本质是goroutine  当新开的线程没结束,主线程已经结束了,所以要想打印,就得等待一会
        go test()
        go test()
        go test()
        go test()
        go test()    //是开了好多,速度很快
        time.Sleep(time.Second*2)//Second表示秒 ,此时表示睡2秒
    }

    信道

      也叫管道,通道,go是csp管道模型进行通信

    package main
    
    import (
        "fmt"
    )
    
    //信道
    //信道也是一个变量,信道运输的类型必须固定
    // 重点:信道的放值和取值在默认情况下都是阻塞的
    // 单向信道,即只能放或者只能取
    // 关闭信道,信道关闭后就不能再放取值了 close(信道名),用rang
    func test1(c chan bool)  {
        fmt.Println("hello go")
        //一旦执行完了,在信道中放入一个值  ***********++++++++++
        c <-true  //向信道中放值
    }
    
    
    func main() {
        //定义一个信道,关键字chan 后面跟信道类型
        //信道的空值是 nil 引用类型
        //var a chan int   //表示定义了一个int类型的信道,该信道只能运输int类型的数据
        //fmt.Println(a)
    
        //信道定义并初始化
        var a chan int =make(chan int)
        fmt.Println(a)
        //重点:放值和取值
        //箭头向信道变量,就是往信道中放值
        a <-1
        //箭头向外,表示从信道中取值  <-a 表示从信道取出来的值不要了(没赋值给变量)
        var b int= <-a
        fmt.Println(b)
        //信道默认情况下,取值和赋值都是阻塞的,就是一旦向信道中放入一个值,程序就卡在这里,不会继续向下执行,
        //此时必须另一个协程把它取走,程序才会继续执行,如果这个协程取,里面没有值,这个协程也会卡在这里
    
    
        //定义一个信道
        var c chan bool=make(chan bool)  //必须初始化
        go test1(c)
        //从信道中取出值,***********++++++++++
        d:=<-c
        fmt.Println(d)
        //time.Sleep(time.Second*2)
    
    }

     用rang循环,

    3,缓冲信道

      信道的本质是刚开始信道里并没有放值,所以才会阻塞,此时放是放不进去的,只有有另一个去取的时候,两者一对接,把值给它了

      缓冲信道,有缓冲大小

    package main
    
    import "fmt"
    
    func main() {
    //    缓冲信道
        //定义一个缓冲大小为3的信道
        var a chan int = make(chan int,3)
        a <-1
        a <-2
        a <-3
        //a <-4   //缓冲大小为3,只能放3个,此时超了,就会阻塞,但是程序不会一直处于阻塞,此时就报死锁错误
        <-a
        <-a  //取值
        b:=<-a
        fmt.Println("xxx")
        fmt.Println(b)  //3   如果再取就会报死锁错误
    }

    缓冲信道例子(协程的利用)

  • 相关阅读:
    又爱又恨的eval
    http_build_query 这个方法会把值为NULL的给干掉
    allow_url_fopen设置
    纠结了下 B 和 STRONG标签区别
    Drupal 发邮件模块 drupal smtp 安装与设置
    php array_merge 和 两数组相加区别
    学历严格正相关于素质 Kai
    表语就是主语补语,靠 Kai
    一些真正有思想的up Kai
    光速不变且最大,换个思路想,非常合理,犹如天经地义【转载】 Kai
  • 原文地址:https://www.cnblogs.com/Fzhiyuan/p/12046342.html
Copyright © 2020-2023  润新知