• go语言学习(六)——并发编程


    并发编程这块断断续续看了挺久的,&感觉还是有地方没有理解。有时间还是要找找正式的代码看一看,不然不知道怎么用啊。

    有些地方不清楚该怎么用,所以下面写的有些乱,再有新的理解再进行补充。。。

    // GoStudy0228 project main.go
    /*
    go语言学习——并发编程
    go语言中支持轻量级线程goroutine
    go语言中以消息机制作为通信方式
    */
    
    package main
    
    import (
    	"fmt"
    	"sync"
    	"time"
    )
    
    func main() { //程序从这开始执行
    	v1 := make(chan [2]int)                //定义chan,这里的chan用来传递一个大小为2的int数组
    	v2 := [2]int{1, 2}                     //定义数组
    	var v3 chan bool = make(chan bool, 10) //另一种定义chan的方式,后面的10,是缓存空间的大小,缓存区在被填满的时候是阻塞的
    	go Add(v1, v3)                         //go关键字启动goroutine
    	v1 <- v2                               //将v2传入chan,在goroutine没有创建的时候,不能向v1传值。
    	var v4 bool = <-v3                     //这里进行阻塞,直到Add函数向chan中传入值以后才能够继续运行。不然可能goroutine没有执行完,main就已经执行完了。
    	fmt.Println(v4)                        //可以将Add函数的isFinished去掉,然后运行看结果,就知道为什么要额外加一个chan了
    
    	v6 := make(chan int, 10)
    	timeOut := make(chan bool)
    	go TimeWait(timeOut) //一种超时处理方式,但目前没有理解号怎么用
    
    	select { //类似于switch,但是只能用于IO方面
    	case <-v6: //
    		fmt.Println("从v6读取数据")
    		break
    	case <-timeOut:
    		fmt.Println("超时")
    		break
    	default:
    		//	fmt.Println("+++++++++++")
    	}
    
    	//------------------------------
    	//单向chan的创建
    	//v21 := make(chan int, 1024) //基于v21创建单向chan
    	//v22 := <-chan int(v21)      //只读
    	//v23 := chan<- int(v21)      //只写
    
    	close(v1) //关闭管道v1
    	_, ok1 := <-v1
    	fmt.Println("v1 is open?", ok1)
    
    	//------------------------------
    	//同步锁
    	//var v31 sync.Mutex int//单一读写
    	//var v32 sync.RWMutex float32//单写多读
    	//v31.Lock()//锁定和解锁要对应,否则死锁卡死
    	//defer v31.Unlock()//这个函数崩溃的时候执行这句,解除锁定
    	//v32.RLock()
    	//defer v32.RUnlock()
    
    	//------------------------------
    	var v41 sync.Once //全局唯一,多个调用的时候,会阻塞,一个执行完才进行下一个
    	v41.Do(func() {
    		fmt.Println("Hello World!!")
    	})
    
    } //程序运行到这退出
    
    func Add(ch chan [2]int, isFinished chan bool) {
    	nums := <-ch //chan被读取前,这里是阻塞的
    	for i := 0; i < 100; i++ {
    		fmt.Println("NO.", i, ":", nums[0]+nums[1])
    	}
    
    	isFinished <- true
    }
    
    func TimeWait(isFinished chan bool) { //等待函数
    	time.Sleep(1) //等待一秒
    	isFinished <- true
    }
    
    /*
    几种多线程的方式
    1.多进程,操作系统层面,开销大
    2.多线程,系统层面,使用最多,最有效,开销较大,高并发对性能有影响
    3.基于回掉的非阻塞/异步IO,通过事件驱动方式使用异步IO,尽可能少用线程,降低开销,但编程比多线程要复杂
    4.协程,有效解决高并发问题,系统开销极小,编程简单,结构清晰,但是需要语言支持(或者用户自行拓展)
    */
    
    /*
    线程间通信:共享内存模式,消息传递模式
    */
    

    //:)

  • 相关阅读:
    每天学一点MATLAB函数——文件编程函数
    每天学一点MATLAB函数——软件操作函数(1)
    C# 杂记
    ActiveX控件注册与反注册
    First Java Graphic Program
    判断式
    两个仿函数示例
    STL文件的读取与显示
    SQLite数据库(一)
    机器学习--如何理解Accuracy, Precision, Recall, F1 score
  • 原文地址:https://www.cnblogs.com/singledigit/p/6516183.html
Copyright © 2020-2023  润新知