关于go中并发的初步理解
1.一些概念的介绍:
| 概念 | 描述 |
| 进程 |
在内存中的程序。有自己独立的独占的虚拟 CPU 、虚拟的 Memory、虚拟的 IO devices。 (1) 每一进程占用独立的地址空间。 此处的地址空间包括代码、数据及其他资源。 |
| 线程 |
轻量级进程。在现代操作系统中,是进程中程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。 (1) 多个线程共享进程的地址空间(代码、数据、其他资源等)。 (2) 线程间的通信开销较少且比较简单。 (3) 线程间的切换开销也较小。 |
| 协程 | 轻量级线程。 是可以并发执行的函数,由编译或用户指定位置将控制权交给协程调度程序执行的方式。它是非抢占式的,可以避免反复系统调用,还有进程切换造成的开销,给你上几千个逻辑流,也称用户级别线程。 |
| 逻辑处理器 | 每个逻辑处理器都会绑定一个线程,并负责goroutine的执行 |
| 并发 | 并发是以时间段为维度,即在单位时间内,同时完成多件事。 |
| 并行 | 并行是以时间点为维度,即在某个时间点,同时完成多件事。 |
| 同步与异步 | 同步和异步针对应用程序而言,关注的是程序中间的协作关系,一般用于应用程序与内核的交互,同步即等待或是轮询;异步则是直接返回,完成后通知应用程序。 |
| 阻塞与非阻塞 | 阻塞与非阻塞关注的是单个进程的执行状态,一般用于网络io中,阻塞即需要等待,不会立即返回;非阻塞则会立刻返回。 |
| 上下文 | 上下文是一种非常泛化的概念,可以理解为程序执行的环境变量。 |
2.关于并发和并行的理解

解释一:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
解释二:并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。
解释三:在一台处理器上“同时”处理多个任务,在多台处理器上同时处理多个任务。如hadoop分布式集群
3.并发实例:
每当执行go func,就会创建一个goroutine,在Go语言中,goroutine就是协程。每个goroutine的结构体中有一个sched域就是用于保存自己上下文的。这样,goroutine就可以被换出去,再换进来。这种上下文保存在用户态完成,不必陷入到内核,非常的轻量,切换速度很快。有的协程运行到一定时候就主动调用yield放弃自己的执行,把自己再次放回到任务队列中等待下一次调用时机等。
func trace(start, end int8) {
for i:=start; i<=end; i++{
fmt.Printf("%c ", i)
time.Sleep(time.Second)
}
}
func main() {
runtime.GOMAXPROCS(1) //限制只有一个逻辑处理器
var wg sync.WaitGroup //用于等待所有协程都完成
wg.Add(2)
go func(){
defer wg.Done()//程序退出的时候执行
trace('a', 'f')
}()
go func(){
defer wg.Done()//程序退出的时候执行
trace('A', 'F')
}()
wg.Wait() //等待所有协程的完成
}
上面的程序使用runtime.GOMAXPROCS(1)来分配一个逻辑处理器供调度器使用,两个goroutine将被该逻辑处理器调度并发执行。输出如下:
A a b B C c d D E e f F G g h H I i j J
在go语言中,“有函数调用,就有机会被调度器调度”,在上面案例中trace方法里面调用了time.sleep()函数的目的,就是让当前运行goroutine有机会被调度器调度,进剥夺该goroutine的执行权,让其他的goroutine执行。所以上面代码打印的结果是大小写字母,交替的输出。如果注销掉”time.sleep()”,输出结果为:
A B C D E F G H I J a b c d e f g h i j
另一个比较好的例子:
package main import (
"fmt"
"sync"
) //声明一个全局变量
var waitgroup sync.WaitGroup func Afunction(shownum int) {
fmt.Println(shownum)
waitgroup.Done() //任务完成,将任务队列中的任务数量-1,其实.Done就是.Add(-1)
} func main() {
for i := 0; i < 10; i++ {
waitgroup.Add(1) //每创建一个goroutine,就把任务队列中任务的数量+1
go Afunction(i)
}
waitgroup.Wait() //.Wait()这里会发生阻塞,直到队列中所有的任务结束就会解除阻塞
}
4.并发通信
只使用wg.add和wg.Wait显然是不能满足我们的需要的,这时候就需要用到go中的goroutines和通道channel处理并发了。在Go中,所有I/O都被阻塞,通过goroutines和通道channel处理并发,而不是回调和异步。通道channel主要负责在并发过程中,实现通信。通道channel是类型相关的,一个通道channel只能传递一种数据类型的值。
参考:http://www.findme.wang/blog/detail/id/427.html
关于go中并发的初步理解的更多相关文章
- Storm中并发程度的理解
Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...
- 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感
关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...
- Jmeter中一些概念的理解——90%响应时间、事务、并发
一.90%响应时间(参考虫师博客) 90%Line 一组数由小到大进行排列,找到他的第90%个数(假如是12),那么这个数组中有90%的数将小于等于12 . 用在性能测试的响应时间,也就是90%请求 ...
- go---weichart个人对Golang中并发理解
个人觉得goroutine是Go并行设计的核心,goroutine是协程,但比线程占用更少.golang对并发的处理采用了协程的技术.golang的goroutine就是协程的实现. 十几个gorou ...
- Mysql加锁过程详解(7)-初步理解MySQL的gap锁
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Spring学习笔记--环境搭建和初步理解IOC
Spring框架是一个轻量级的框架,不依赖容器就能够运行,像重量级的框架EJB框架就必须运行在JBoss等支持EJB的容器中,核心思想是IOC,AOP,Spring能够协同Struts,hiberna ...
- Graph Cuts初步理解
一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...
- springBoot(1)---springboot初步理解
springboot初步理解 在没有用SpringBoot之前,我们用spring和springMVC框架,但是你要做很多比如: (1)配置web.xml,加载spring和spring mvc 2) ...
- HashMap在JDK1.8中并发操作,代码测试以及源码分析
HashMap在JDK1.8中并发操作不会出现死循环,只会出现缺数据.测试如下: package JDKSource; import java.util.HashMap; import java.ut ...
随机推荐
- 网络安全知识--PHP代码审计/Web For Pantesters 的 XSS
用到 ** WEB FOR Pentester** 注意区分单引号双引号. 常见代码 审计工具 wamp,dwva,zvuldrill,burpsuite,seay源代码审计系统... 1 xss W ...
- hautoj 1268 小天使改名
1268: 小天使改名 时间限制: 2 秒 内存限制: 128 MB提交: 437 解决: 123提交 状态 题目描述 小天使的b站帐号被大家发现啦.于是小天使决定改名,将他原有ID中的两个不同位 ...
- docker安装CentOS7及JNI使用相关过程记录
docker pull centos:centos7(拉取镜像) docker run -itd --name centos-test centos:centos7 (运行容器) docker exe ...
- sdutoj2887
#include <stdio.h> #include <math.h> int main(){ int px,tx;double alpha; int T;scanf(&qu ...
- Python+argparse+notebook
argparse"应用"于jupyter-notebook中 args.xx =======================>> args["xx" ...
- 如何使用 js 实现相似图片搜索
如何使用 js 实现相似图片搜索 以图搜图 https://www.google.com/imghp?hl=en https://www.google.com/imghp?hl=zh https:// ...
- React render twice bug
React render twice bug React bug constructor render twice bug update render twice bug StrictMode htt ...
- flutter 1.5 in action
flutter 1.5 in action https://flutter.dev/docs/get-started/flutter-for/react-native-devs https://flu ...
- full page screen capture in js
full page screen capture in js html2canvas https://html2canvas.hertzen.com/ https://github.com/nikla ...
- HTTP/1.1 有点慢,我想优化下!
问你一句:「你知道 HTTP/1.1 该如何优化吗?」 我想你第一时间想到的是,使用 KeepAlive 将 HTTP/1.1 从短连接改成长链接. 这个确实是一个优化的手段,它是从底层的传输层这一方 ...