Goroutine是如何工作的_转

【自取】最近整理的,有需要可以领取学习:

参考:GMP 原理与调度 http://topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/GMP%E5%8E%9F%E7%90%86%E4%B8%8E%E8%B0%83%E5%BA%A6.html

Goroutine是如何工作的_转

转自:http://tonybai.com/2014/11/15/how-goroutines-work/

golangweekly的第36期Go Newsletter中我发现一篇短文“How Goroutines Work” ,其作者在参考了诸多资料后,简短概要地总结了一下 Goroutine的工作原理,感觉十分适合刚入门的Gophers(深入理解Goroutine调度的话,可以参考Daniel Morsing的”The Go scheduler” )。这里粗译如下。

一、Go语言简介

如果你是Go语言新手,或如果你对”并发(Concurrency)不是并行(parallelism)”这句话毫无赶脚,那么请看一下Rob Pike大神关于这个主题的演讲吧,演讲共30分 钟,我敢保证你在这个演讲上花费30分钟是绝对值得的。

总结一下两者(Concurrency和Parallelism)的不同:”当人们听到并发(Concurrency)这个词时,总是会想起并行 (Parallelism),它们之间有相关性,但却是两个明显不同的概念。在编程领域,并发(Concurrency)是独立的执行过程 (Process)的组合,而并行(Parallelism)则是计算(可能是相关联的)的同时执行。并发(Concurrency)是关于同时 应对很多事情(deal with lots of things),而并行(Parallelism)则是同时做许多事情(do lots of things)”。(Rob Pike的”Concurrency is not parallelism“)

Go语言支持我们编写并发(Concurrent)的程序。它提供了Goroutine以及更重要的在Goroutines之间通信的能力。这里 我们将聚焦在前者(译注:指并发)。

二、Goroutines和Thread s

Goroutine是一个简单的模型:它是一个函数,与其他Goroutines并发执行且共享相同地址空间。Goroutines的通常用法是根据需要创建尽可 能的Groutines,成百上千甚至上万的。这种用法对于那些习惯了使用C++或Java的程序员来讲可能会有些奇怪。创建这么多 goroutines势必要付出不菲的代价?一个操作系统线程使用固定大小的内存作为它的执行栈,当线程数增多时,线程间切换的代价也是相当的 高。这也是每处理一个request就创建一个新线程的服务程序方案被诟病的原因。

不过Goroutine完全不同。它们由Go运行时初始化并调度,操作系统根本看不到Goroutine的存在。所有的goroutines都是 活着的,并且以多路复用的形式运行于操作系统为应用程序分配的少数几个线程上。创建一个Goroutine并不需要太多内存,只需要8K的栈空间 (在Go 1.3中这个Size发生了变化)。它们根据需要在堆上分配和释放内存以实现自身的增长。

Go运行时负责调度Goroutines。Goroutines的调度是协作式的,而线程不是。这意味着每次一个线程发生切换,你都需要保存/恢 复所有寄存器,包括16个通用寄存器、PC(程序计数器)、SP(栈指针)、段寄存器(segment register)、16个XMM寄存器、FP协处理器状态、X AVX寄存器以及所有MSR等。而当另一个Goroutine被调度时,只需要保存/恢复三个寄存器,分别是PC、SP和DX。Go调度器和任何现代操作 系统的调度器都是O(1)复杂度的,这意味着增加线程/goroutines的数量不会增加切换时间,但改变寄存器的代价是不可忽视的。

由于Goroutines的调度是协作式的,一个持续循环的goroutine会导致运行于同一线程上的其他goroutines”饿死”。在 Go 1.2中,这个问题或多或少可以通过在进入函数前间或地调用Go调度器来缓解一些,因此一个包含非内联函数调用的循环是可以被调度器抢占的。

三、Goroutine阻塞

只要阻塞存在,它在OS线程中就是不受欢迎的,因为你拥有的线程数量很少。如果你发现大量线程阻塞在网络操作或是Sleep操作上,那就是问题, 需要修正。正如前面提到的那样,Goroutine是廉价的。更关键地是,如果它们在网络输入操作、Sleep操作、Channel操作或 sync包的原语操作上阻塞了,也不会导致承载其多路复用的线程阻塞。如果一个goroutine在上述某个操作上阻塞,Go运行时会调度另外一 个goroutine。即使成千上万的Goroutine被创建了出来,如果它们阻塞在上述的某个操作上,也不会浪费系统资源。从操作系统的视角来看,你的程序的行为就像是一个事件驱动的C程序似的。

四、最后的想法

就是这样,Goroutines可以并发的运行。不过和其他语言一样,组织两个或更多goroutine同时访问共享资源是很重要的。最好采用Channel在不同Goroutine间传递数据。

最后,虽然你无法直接控制Go运行时创建的线程的数量,但可以通过调用runtime.GOMAXPROCS(n)方法设置变量GOMAXPROCS来设 定使用的处理器核的数量。提高使用的处理器核数未必能提升你的程序的性能,这取决于程序的设计。程序剖析诊断工具(profiling tool)可以用来检查你的程序使用处理器核数的真实情况。

Original: https://www.cnblogs.com/embedded-linux/p/13398523.html
Author: yuxi_o
Title: Goroutine是如何工作的_转

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/8705/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • git rebase -i HEAD~3合并多个提交为一个提交

    场景:新功能在本地的dev_feat分支开发过程中,提交了多次,生成了多个commit id,开发测试完成后将新功能合并到dev分支上,但是不想要这些提交记录,那么可以将多个com…

    Linux 2022年8月30日
    0290
  • Ubuntu虚拟机JeOS安装-2016.08.28

    根据官网的说明JeOS的镜像已经在官方不发行了,所以你在别的帖子里看到的安装jeos的镜像地址已经不适用了。 那么应该如何安装这种最小版本的linux操作系统呢? 镜像文件地址: …

    Linux 2022年8月26日
    0270
  • LInux tty 非阻塞配置以及安全读取数据方法

    *串口配置 char read_data[10], *write_char = "abcd01234\0"; int fd_a, fd_b, read_len …

    Linux 2022年8月24日
    0250
  • Linux 开机启动 shell 脚本

    步骤如下:1.写好 shell 脚本注意:执行命令前,需要先 cd 到命令文件所在的目录,如:需要执行 /home/tommy/start 文件, 2.书写相关的 service …

    Linux 2022年8月24日
    0310
  • Centos 7.x 线上安装 Kubernetes

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 安装依赖包 yum install -y conntrack ntpdate ntp ipvsadm ipset jq ipta…

    Linux 2022年9月10日
    0210
  • Git 本地分支 本地分支的新建与合并

    本地分支的新建与合并 新建分支 首先,我们假设你正在你的项目上工作,并且在 master 分支上已经有了一些提交。 Figure 18. 一个简单提交历史 现在,你已经决定要解决你…

    Linux 2022年8月30日
    0250
  • Linux裸设备管理详解–

    裸设备概述 裸设备:也叫裸分区(原始分区),是一种没有经过格式化,不被Unix/Linux通过文件系统来读取的特殊字符设备。裸设备可以绑定一个分区,也可以绑定一个磁盘。字符设备:对…

    Linux 2022年8月13日
    0350
  • git log 常用命令

    git log –patch -2,–patch可以显示每次提交之间的diff,同时-n可以指定显示最近几个commit。这个是很有用的,可以看最近两次co…

    Linux 2022年8月30日
    0290
  • Windows下配置Redis多实例

    方法一:新建目录创建Redis实例 1.将你的redis安装目录复制一份,命名为Redis6380 2.用命令行CMD工具进入到该目录下 3.执行创建redis6380服务的命令:…

    Linux 2022年9月14日
    0190
  • Powershell 测量命令执形时间

    powershell -Command (Measure-Command { "docker build –no-cache -f 2.2/Dockerfile 2.2…

    Linux 2022年9月14日
    0250
  • Linux命令——pidof

    参考:Linux pidof Command Examples To Find PID of A Program/Command Linux pidof Command Tutor…

    2022年8月24日
    0250
  • Ubuntu 汉化及kate汉化和使用自带终端的解决方式

    汉化方法:1,打开屏幕上方的"system"(系统),里面有个"Administration"(系统管理),选择"Snaptic …

    Linux 2022年8月26日
    0300
  • linux生成iso

    genisoimage -r -J -joliet-long -o xxx.iso /xxxxx/xxxxxx Original: https://www.cnblogs.com/…

    Linux 2022年8月26日
    0450
  • Linux expect 使用(免密登录跳板机)

    登录公司的跳板机是挺麻烦的事,首先要ssh,然后输入密码,有的公司可能还要动态密码,前两步操作都是固定的,所以能免去前两步的操作就会方便很多(线上出问题也能尽快登上去,免得紧张密码…

    Linux 2022年8月26日
    0260
  • 什么?Android上面跑Linux?

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 前言 众所周知,现在程序员因为工作、个人兴趣等对各种系统的需求越来越大,部分人电脑做的还是双系统。其中,比较常见的有各种模拟器、…

    Linux 2022年9月10日
    0240
  • Cloud Computing Causing Digital Business Transformation

    2015-04-13 Cloud Computing Causing Digital Business Transformation We hear all about the c…

    2022年8月30日
    0260
  • linux内核设计模式

    原文来自:http://lwn.net/Articles/336224/ 选择感兴趣内容简单翻译了下: 在内核社区一直以来的兴趣是保证质量.我们需要保证和改善质量是显而易见的.但是…

    Linux 2022年8月26日
    0280
  • Linux Shell 之 对文件中的行、单词、字符进行迭代

    在进行文本文件进行处理时,对文件件中的行、单词、字符进行迭代和遍历是非常常用的操作。而将一个简单的循环用于迭代,再加上来自stdin或文件的重定向,这就是对文件中的行、单词、和字符…

    Linux 2022年8月24日
    0260
  • Linux驱动开发学习笔记(1):LINUX驱动版本的hello world

    1、关于目录/lib/modules/2.6.9-42.ELsmp/build/ 这个是内核源码所在的目录一般使用这样的命令进入这个目录:cd /lib/modules/$(una…

    Linux 2022年8月20日
    0300
  • 基于linux下的krpano的使用

    鉴于目前网络上关于krpano的使用和介绍少之又少,结合自己的学习和使用经历,做个总结和记录。 下载地址: linux windows: 可自行百度,这块网上的资源比较多,建议下载…

    Linux 2022年8月26日
    0300
  • docker安装redis

    首先考虑需要安装的redis版本,我这里是安装的redis 6.0.16,如果宿主机没有,那么就docker pull redis:6.0.16 一、指定redis配置文件 我的宿…

    Linux 2022年9月14日
    0360
  • CentOS通过yum升级Openssh8.x

    制作 RPM 包 安装相关依赖 # yum install rpm-build zlib-devel openssl-devel gcc perl-devel pam-devel …

    Linux 2022年8月30日
    0260
  • Git积累

    1.git配置信息(1).配置用户和邮箱git config –global user.name ‘your_name’git config &…

    Linux 2022年8月30日
    0330
  • SpringBoot学习笔记——Redis Template

    Springboot可以通过redis template和redis进行交互,使用方法如下 可以参考这个系列的文章: 【快学springboot】11.整合redis实现sessi…

    Linux 2022年9月14日
    0410
  • Linux录屏软件

    如何查找录屏软件 apt-cache search screen record libutempter-dev – privileged helper for utmp/wtmp …

    Linux 2022年8月26日
    0300
  • awk按顺序去除重复行

    # root @ c7bit1 in ~ [16:43:40] $ cat test a b c d b g # root @ c7bit1 in ~ [16:46:27] C:2…

    Linux 2022年8月26日
    0290

发表回复

登录后才能评论
免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部