• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

小白也看得懂Goroutine | 青训营

武飞扬头像
Cold0303
帮助1

引言

当我们计算1-200000有多少个素数时,依照之前所学知识写出来的代码,相当于是一个人一个数一个数的计算,这样运行时间就很慢。当我们使用goroutine(协程),就相当于多个人同时计算,极大地提高了运行速度。

进程和线程的关系

1.进程就是程序在操作系统中的一次执行过程,是系统资源分配和调度的基本单位。在任务管理器中可以查看当前系统的进程。

学新通 2.线程是进程的一个执行示例,是程序执行的最小单元。而一个进程可以至少有一个线程。

3.一个程序也至少有一个进程,也可能多个,也就是网上所说的多开。

并发和并行的区别

  1. 程序在单核运行,就是并发
  2. 程序在多核运行,就是并行

并发:假如有十个线程,在单核运行,所以它们是cpu在极短时间内执行一个线程,随后切换至另一线程执行,因为时间极短,所以感觉像是在同时运行,实际上不是。

并行:因为CPU都是多核的,假设16核CPU,执行10个线程,cpu1会执行一个线程,cpu2会执行一个线程......线程各自在不同CPU同时执行。

区别:用比喻来形容,并发相当于十个人玩一台电脑,而并行是十个人每个人都有电脑玩

Go协程和主线程

在Go中,一个Go主线程可以开启多个协程,此处的协程,可以理解为一种轻量级的线程。所以协程和主线程的关系其实和上文提到的进程和线程的关系类似。

代码演示

在下面的代码中,我试图同时输出“hello,world”和“hello,golang”。其中我使用了time包中的time.Slepp(),作用是间隔一秒输出,以便观察输出顺序。先让我们看一下没开启协程的结果:

学新通 可以看出它是先输出完“hello,world”再输出“hello,golang”的。下面我们看一下开启协程后:

学新通 我们很容易看出,两句话是同时输出,这就是开启了协程的效果。重点:程序的结束是以主线程为主,当主线程运行完后,不管协程是否运行完,都会结束。下面我们将print()函数打印次数改为10,可运行结果出来,print()函数还是只打印了5次。

学新通

资源竞争问题

如图,图上写了一段代码,求出1-20的阶乘,并放进map中,当我们直接运行后,程序却会报错。这是因为我开启了20个线程,但它们会同时往map中写入,这就造成了资源竞争

学新通

现在,我们需要使用全局互斥锁来解决这个问题。当第一个协程往map中写入,会加锁,写完后则会解锁。后来的协程发现map是加锁的,就会进入队列等待,直到map解锁。这里我们引用了sync包。

学新通 到这里又出现了个问题,上文说过,程序结束是以主程序结束为主。那么,主线程如何知道协程是否结束呢?这里就提出了协程的通讯问题,我们将在下一章提出解决方案,Channel管道)。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbccih
系列文章
更多 icon
同类精品
更多 icon
继续加载