1.一些概念的介绍:

概念 描述
进程

在内存中的程序。有自己独立的独占的虚拟 CPU 、虚拟的 Memory、虚拟的 IO devices。

(1) 每一进程占用独立的地址空间。 此处的地址空间包括代码、数据及其他资源。
(2) 进程间的通信开销较大且受到许多限制。 对象(或函数)接口、通信协议
(3) 进程间的切换开销也较大。 又称Context Switch。上下文包括代码、数据、堆栈、处理器状态、资源。

线程

轻量级进程。在现代操作系统中,是进程中程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

(1) 多个线程共享进程的地址空间(代码、数据、其他资源等)。
线程也需要自己的资源,如程序计数器、寄存器组、调用栈等。

(2) 线程间的通信开销较少且比较简单。
因为共享而减少了需要通信的内容。
但也因为充分共享而无法对共享资源进行保护。

(3) 线程间的切换开销也较小。
只需保存每一线程的程序计数器、寄存器组、堆栈等空间。
不必切换或复制整个地址空间,从而成本大为降低(约1/10)

协程 轻量级线程。 是可以并发执行的函数,由编译或用户指定位置将控制权交给协程调度程序执行的方式。它是非抢占式的,可以避免反复系统调用,还有进程切换造成的开销,给你上几千个逻辑流,也称用户级别线程。
逻辑处理器 每个逻辑处理器都会绑定一个线程,并负责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中并发的初步理解的更多相关文章

  1. Storm中并发程度的理解

    Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...

  2. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  3. Jmeter中一些概念的理解——90%响应时间、事务、并发

    一.90%响应时间(参考虫师博客) 90%Line  一组数由小到大进行排列,找到他的第90%个数(假如是12),那么这个数组中有90%的数将小于等于12 . 用在性能测试的响应时间,也就是90%请求 ...

  4. go---weichart个人对Golang中并发理解

    个人觉得goroutine是Go并行设计的核心,goroutine是协程,但比线程占用更少.golang对并发的处理采用了协程的技术.golang的goroutine就是协程的实现. 十几个gorou ...

  5. Mysql加锁过程详解(7)-初步理解MySQL的gap锁

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  6. Spring学习笔记--环境搭建和初步理解IOC

    Spring框架是一个轻量级的框架,不依赖容器就能够运行,像重量级的框架EJB框架就必须运行在JBoss等支持EJB的容器中,核心思想是IOC,AOP,Spring能够协同Struts,hiberna ...

  7. Graph Cuts初步理解

    一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...

  8. springBoot(1)---springboot初步理解

    springboot初步理解 在没有用SpringBoot之前,我们用spring和springMVC框架,但是你要做很多比如: (1)配置web.xml,加载spring和spring mvc 2) ...

  9. HashMap在JDK1.8中并发操作,代码测试以及源码分析

    HashMap在JDK1.8中并发操作不会出现死循环,只会出现缺数据.测试如下: package JDKSource; import java.util.HashMap; import java.ut ...

随机推荐

  1. 网络安全知识--PHP代码审计/Web For Pantesters 的 XSS

    用到 ** WEB FOR Pentester** 注意区分单引号双引号. 常见代码 审计工具 wamp,dwva,zvuldrill,burpsuite,seay源代码审计系统... 1 xss W ...

  2. hautoj 1268 小天使改名

    1268: 小天使改名 时间限制: 2 秒  内存限制: 128 MB提交: 437  解决: 123提交 状态 题目描述 小天使的b站帐号被大家发现啦.于是小天使决定改名,将他原有ID中的两个不同位 ...

  3. docker安装CentOS7及JNI使用相关过程记录

    docker pull centos:centos7(拉取镜像) docker run -itd --name centos-test centos:centos7 (运行容器) docker exe ...

  4. sdutoj2887

    #include <stdio.h> #include <math.h> int main(){ int px,tx;double alpha; int T;scanf(&qu ...

  5. Python+argparse+notebook

    argparse"应用"于jupyter-notebook中 args.xx =======================>> args["xx" ...

  6. 如何使用 js 实现相似图片搜索

    如何使用 js 实现相似图片搜索 以图搜图 https://www.google.com/imghp?hl=en https://www.google.com/imghp?hl=zh https:// ...

  7. React render twice bug

    React render twice bug React bug constructor render twice bug update render twice bug StrictMode htt ...

  8. flutter 1.5 in action

    flutter 1.5 in action https://flutter.dev/docs/get-started/flutter-for/react-native-devs https://flu ...

  9. full page screen capture in js

    full page screen capture in js html2canvas https://html2canvas.hertzen.com/ https://github.com/nikla ...

  10. HTTP/1.1 有点慢,我想优化下!

    问你一句:「你知道 HTTP/1.1 该如何优化吗?」 我想你第一时间想到的是,使用 KeepAlive 将 HTTP/1.1 从短连接改成长链接. 这个确实是一个优化的手段,它是从底层的传输层这一方 ...