zoukankan      html  css  js  c++  java
  • go协程

    一。并发&并行

    一个应用程序  ---> 一个进程 ---> 运行在自己内存地址空间里的独立执行体 ---> 同一个内存地址空间的一起工作的多个线程

    一个并发程序 ---> 多个线程来执行任务 ---> 某个时间点同时运行在多核或者多处理器 ---> 并发&并行

                                                           ---> 某个时间点同时运行在单个处理器     -----> 并发&不并行

    并行是一种通过使用多处理器以提高速度的能力。所以并发程序可以是并行的,也可以不是。

    公认的,使用多线程的应用难以做到准确,最主要的问题是内存中的数据共享,它们会被多线程以无法预知的方式进行操作,导致一些无法重现或者随机的结果(称作 竞态

    并发方式:

    1.确定性的(明确定义排序)

    2.非确定性的(加锁/互斥从而未定义排序)---> 竞态

    不要使用全局变量或者共享内存,它们会给你的代码在并发运算的时候带来危险。

    解决之道:

    1.同步不同的线程,对数据加锁,这样同时就只有一个线程可以变更数据

    2.有个被称作 Communicating Sequential Processes(顺序通信处理)(CSP, C. Hoare 发明的)

    3.还有一个叫做 message passing-model(消息传递)(已经运用在了其他语言中,比如 Erlang)

    二。go的协程

    在 Go 中,应用程序并发处理的部分被称作 goroutines(协程)

    协程 ---> 工作在相同的地址空间 ---> 共享内存的方式一定是同步的;这个可以使用 sync 包来实现(不推荐)

           ---> 使用 channels 来同步协程

    特点:

    1.使用少量的内存和资源:使用 4K 的栈内存就可以在堆中创建它们

    2.对栈进行了分割,从而动态的增加(或缩减)内存的使用;栈的管理是自动的,但不是由垃圾回收器管理的,而是在协程退出后自动释放

    3.协程可以运行在多个操作系统线程之间,也可以运行在线程之内

    4.使用少量的操作系统线程就能拥有任意多个提供服务的协程,而且 Go 运行时可以聪明的意识到哪些协程被阻塞了,暂时搁置它们并处理其他协程

    5.存在两种并发方式:确定性的(明确定义排序)和非确定性的(加锁/互斥从而未定义排序)。Go 的协程和通道理所当然的支持确定性的并发方式(例如通道具有一个 sender 和一个 receiver)

    实现形式:

    关键字 go 调用 ---> 一个函数或者方法 ---> 在当前的计算过程中开始一个同时进行的函数 ---> 在相同的地址空间中并且分配了独立的栈(栈分割)

    协程的栈会根据需要进行伸缩,不出现栈溢出;开发者不需要关心栈的大小。当协程结束的时候,它会静默退出:用来启动这个协程的函数不会得到任何的返回值

    三。go协程并行:

    Go 默认没有并行指令,只有一个独立的核心或处理器被专门用于 Go 程序,不论它启动了多少个协程;所以这些协程是并发运行的,但他们不是并行运行的:同一时间只有一个协程会处在运行状态

    在 gc 编译器下(6g 或者 8g)你必须设置 GOMAXPROCS 为一个大于默认值 1 的数值来允许运行时支持使用多于 1 个的操作系统线程,所有的协程都会共享同一个线程除非将 GOMAXPROCS 设置为一个大于 1 的数。当 GOMAXPROCS 大于 1 时,会有一个线程池管理许多的线程。通过 gccgo 编译器 GOMAXPROCS 有效的与运行中的协程数量相等。假设 n 是机器上处理器或者核心的数量。如果你设置环境变量 GOMAXPROCS>=n,或者执行 runtime.GOMAXPROCS(n),接下来协程会被分割(分散)到 n 个处理器上。更多的处理器并不意味着性能的线性提升。有这样一个经验法则,对于 n 个核心的情况设置 GOMAXPROCS 为 n-1 以获得最佳性能,也同样需要遵守这条规则:协程的数量 > 1 + GOMAXPROCS > 1。

    所以如果在某一时间只有一个协程在执行,不要设置 GOMAXPROCS!

    还有一些通过实验观察到的现象:在一台 1 颗 CPU 的笔记本电脑上,增加 GOMAXPROCS 到 9 会带来性能提升。在一台 32 核的机器上,设置 GOMAXPROCS=8 会达到最好的性能,在测试环境中,更高的数值无法提升性能。如果设置一个很大的 GOMAXPROCS 只会带来轻微的性能下降;设置 GOMAXPROCS=100,使用 top 命令和 H 选项查看到只有 7 个活动的线程。

    增加 GOMAXPROCS 的数值对程序进行并发计算是有好处的;

    总结:GOMAXPROCS 等同于(并发的)线程数量,在一台核心数多于1个的机器上,会尽可能有等同于核心数的线程在并行运行。

     

  • 相关阅读:
    springboot + self4j 学习笔记
    git 创建本地分支,并且推送到远程分支
    windows 下生成 ssh key
    Topshelf
    ADSL拨号连接
    EF中使用Contains方法
    elasticsearch中的概念简述
    CriticalFinalizerObject的作用
    sqlserver中的统计语法
    Windbg简单介绍
  • 原文地址:https://www.cnblogs.com/derekchen/p/9767046.html
Copyright © 2011-2022 走看看