一。并发&并行

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

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

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

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

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

并发方式:

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个的机器上,会尽可能有等同于核心数的线程在并行运行。

go协程的更多相关文章

  1. Python(八)进程、线程、协程篇

    本章内容: 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 线程 Threading用于提供线程相关的操作.线程是应用 ...

  2. Lua的协程和协程库详解

    我们首先介绍一下什么是协程.然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,最后介绍一下协程的复杂用法. 一.协程是什么? (1)线程 首先复习一下多线程.我们都知道线程——Thre ...

  3. 协程--gevent模块(单线程高并发)

    先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...

  4. Python 【第五章】:线程、进程和协程

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...

  5. 进击的Python【第十章】:Python的socket高级应用(多进程,协程与异步)

    Python的socket高级应用(多进程,协程与异步)

  6. unity 协程

    StartCoroutine在unity3d的帮助中叫做协程,意思就是启动一个辅助的线程. 在C#中直接有Thread这个线程,但是在unity中有些元素是不能操作的.这个时候可以使用协程来完成. 使 ...

  7. golang 裸写一个pool池控制协程的大小

    这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mid=2653369770& ...

  8. 从Erlang进程看协程思想

    从Erlang进程看协程思想 多核慢慢火了以后,协程类编程也开始越来越火了.比较有代表性的有Go的goroutine.Erlang的Erlang进程.Scala的actor.windows下的fibr ...

  9. Unity学习疑问记录之协程

    http://blog.csdn.net/huang9012/article/details/38492937 总结:1.协程相当于多线程但不是,(尽管它们看上去是这样的),它们运行在同一线程中,跟普 ...

  10. python中协程

    在引出协成概念之前先说说python的进程和线程. 进程: 进程是正在执行程序实例.执行程序的过程中,内核会讲程序代码载入虚拟内存,为程序变量分配空间,建立 bookkeeping 数据结构,来记录与 ...

随机推荐

  1. ssh采用expect实现自动输入密码登录、拷贝

    1. 引言 最近做了一个项目,需要频繁与另一台主机进行文件的传输:中间想到了很多方式:FTP.samba.curl等,但是还是感觉scp最好用. SCP使用教程可参阅:http://www.jb51. ...

  2. USB 驱动(监测鼠标左键的动作)

    (基于 Linux 3.4.2 内核) 可分为以下几个步骤来完成这个驱动: 1. 分配设置一个 usb_driver 结构体 2. 注册这个 usb_driver (如果设备的 id_table 与驱 ...

  3. Extjs 在项目中碰到问题

    1.切换tabpanel,新建tab关闭后再新建报错,在火狐下报错 TypeError: el is null   el.addCls.apply(el, arguments); 这个我在下一篇文章中 ...

  4. 检测到是移动端还是PC端进入页面,加载不同样式表现

    if(/AppleWebKit.*mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alc ...

  5. CentOS7日期时间设置方法以及时间基本概念介绍

    在CentOS 6版本,时间设置有date.hwclock命令,从CentOS 7开始,使用了一个新的命令timedatectl. 一.基本概念 1.1 GMT.UTC.CST.DST 时间 (1) ...

  6. 【Tomcat】压力测试和优化

    一.采用jmeter进行测试 为什么使用jmeter, 它免费开源, 不断发展, 功能逐渐强大. 可以做功能,负载, 性能测试.一套脚本可以同时用于功能和性能测试.Jmeter 有着众多的插件开发者, ...

  7. Linux常用基本命令:三剑客命令之-sed

    sed是一个很强大的文件处理工具,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作 格式:sed [option] [command] [file] 常用命令: a   ∶新 ...

  8. Python: tree data structure

    # 树结构 from pythonds.basic.stack import Stack #pip install pythonds from pythonds.trees.binaryTree im ...

  9. GitHub使用SSHkey进行连接

    SSH key的配置基本是我们使用git必备的配置,配置好可以避免频繁的在git push或者git pull的时候输入账号和密码 本来我的SSH key早就配置好了,结果他不起作用了,那就在配置一次 ...

  10. Vue和React的对比

    今晚我们来搞一搞Vue和React的对比好吧,话不多说今天我们直接开搞可好,各位小老板,开始吧 1. react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入, 所以在react中,是 ...