zoukankan      html  css  js  c++  java
  • Go语言系列三

    package

    • 1> 基本复用模块单元
      • 以首字母大写来表明可被包外代码访问
    • 2> 代码的package可以和所在的目录不一致
    • 3> 同一目录里的Go代码的package要保持一致

    package

    • 1> 通过go get来获取远程依赖

      • go get -u 强制从网络更新远程依赖
    • 2> 注意代码在GitHub上的组织形式,以适应go get

      • 直接以代码路径开始,不要有src

      示例一

      示例二

      go get 下载的包保存在哪里呢?

      一般他会保存在这个目录:$GOPATH/src/import-path , 若你有多个GOPATH(工作区),

      则会保存在第一个工作区中。go env 查看go环境

    init 方法

    • 1> 在main被执行前,所有依赖的package的init方法都会被执行
    • 2> 不同包的init函数按照包导入的依赖关系决定执行顺序
    • 3> 每个包可以有多个init函数
    • 4> 包的每个源文件也可以有多个init函数,这点比较特殊

    依赖管理

    Go未解决的依赖问题

    • 1> 同一环境下,不同项目使用同一包的不同版本
    • 2> 无法管理对包的特定版本的依赖

    vendor路径

    随着Go 1.5 release版本的发布,vendor目录被添加到除了GOPATH和GOROOT之外的依赖目录查找的解决方案

    在Go1.6之前,你需要手动的设置环境变量

    查找依赖包路径的解决方案如下:

    • 1> 当前包下的vendor目录
    • 2> 向上级目录查找,直到找到src下的vendor目录
    • 3> 在GOPATH下面查找依赖包
    • 4> 在GOROOT目录下查找

    常用的依赖管理工具

    godep https://github.com/tools/godep

    glide https://github.com/Masterminds/glide

    dep https://github.com/golang/dep

    安装glide

    • 1> sudo apt install golang-glide
    • 2> glide init
    • 3> glide install

    Thead vs Groutine

    • 1> 创建时默认的stack的大小

      • JDK5以后Java Thread stack 默认为1M
      • Groutine的Stack初始化大小为2K
    • 2> 和KSE (Kernel Space Entity)的对应关系

      • Java Thread 是1 :1
      • Groutine是M:N

      线程关系图

    //错误写法,想想为什么?
    func TestGroutine(t *testing.T) {
    	for i := 0; i < 10; i++ {
    		go func() {
    			fmt.Println(i)
    		}()
    	}
    	time.Sleep(time.Millisecond * 50)
    }
    /* !< output */
    === RUN   TestGroutine
    10
    10
    10
    10
    10
    10
    10
    10
    10
    10
    --- PASS: TestGroutine (0.05s)
    

    共享内存并发机制

    Lock

    Lock lock = ...;
    lock.lock();
    try{
        //process (thread-safe)
    }catch(Exception ex){
    }finally{
        lock.unlock();
    }
    
    

    Lock图

    WaitGroup

    var wg sync.WaitGroup
    for i := 0; i < 5000; i++ {
        wg.Add(1)
        go func() {
            defer func() {
                wg.Done()
            }()
            ...
        }()
    }
    wg.Wait()
    

    CSP并发机制

    Communicating sequential processes

    Actor Model

    CSP vs Actor

    • 1> 和Actor的直接通讯不同,CSP模式则是通过Channel进行通讯的,更松耦合一些

    • 2> Go中channel是有容量限制并且独立于处理Groutine,而如Erlang,Actor模式中的mailbox容量是无限的

      ​ 接收进程也总是被动地处理消息

    Channel

    异步返回

    /* !< java */
    private static FutureTask<String> service() {
        FutureTask<String> task = new FutureTask<String>(()->"Dosomething");
        new Thread(task).start();
        return task;
    }
    
    FutureTask<String> ret = service();
    	System.out.println("Do something else");
    	System.out.println(ret.get());
    

    多路选择和超时控制

    select

    /* !< 多渠道的选择*/
    select {
        case ret := <-retCh1:
        	t.Logf("result %s", ret)
        case ret := <-retCh2:
        	t.Logf("result %s", ret)
        default:
        	t.Error("No one returned")
    }
    
    /* !< 超时控制 */
    select {
    	case ret := <-retCh:
        	t.Logf("result %s", ret)
        case <-time.After(time.Second * 1):
        	t.Error("time out")
    }
    

    channel的关闭

    • 1> 向关闭的channel发送数据,会导致panic
    • 2> v, ok <- ch; ok为bool值,true表示正常接受,false表示通道关闭
    • 3> 所有的channel接收者都会在channel关闭时,立刻从阻塞等待中返回且上述ok值为false,这个广播机制常被利用,进行向多个订阅者同时发送信号, eg: 退出信号

    任务的取消

    Context与任务取消

    关联任务的取消

    Context

    • 1> 根Context:通过context.Background()创建
    • 2> 子Context: context.WithCancel(parentContext)创建
      • ctx, cancel := context.WithCancel(context.Background())
    • 3> 当前Context被取消时,基于它的子context都会被取消
    • 4> 接收取消通知<-ctx.Done()

    并发任务: 仅执行一次

    单例模式(懒汉模式,线程安全)

    /* !< java */
    public class Singleton {
        private static Singleton INSTANCE = null;
        private Singleton(){}
        public static Singleton getlntance() {
            if (ISTANCE == null) {
                synchronized (Singleton.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new Singleton();
                    }
                }
            }
            return INSTANCE;
        }
    }
    
    var once sync.Once
    var obj *SingletonObj
    
    func GetSingletonObj() *SingletonObj {
        once.Do(func() {
            fmt.Printl("Create Singleton obj.")
            obj = &SingletonObj{}
        })
        return obj
    }
    
  • 相关阅读:
    VS 2012 + NDK + ADT 开发(Cocos2d-x 3.1开发)PART 2
    VS 2012 + NDK + ADT 开发(Cocos2d-x 3.1开发)PART 1
    WebView读取SD卡上的HTML
    安卓隐藏控件
    OMNET++安装
    产品质量的核心——概念的完整性
    关于异常
    基类与子类之间的引用转换
    成绩划分 处理异常
    《大道至简 第七、八章》读后感
  • 原文地址:https://www.cnblogs.com/xzpin/p/11602087.html
Copyright © 2011-2022 走看看