当前位置: 首页 > news >正文

Go语言的调度器

简介

Go语言的调度器是一个非常强大的工具,它可以帮助我们轻松地实现并发编程。调度器的工作原理是将多个协程映射到多个操作系统线程上,并根据协程的状态来决定哪个协程应该在哪个线程上运行。

调度器有两种主要策略:

  • 协作式调度: 协作式调度是指协程主动放弃 CPU 时间片,以便其他协程有机会运行。
  • 抢占式调度: 抢占式调度是指调度器强制剥夺一个协程的 CPU 时间片,以便另一个协程可以运行。

Go语言的调度器使用的是抢占式调度算法,这意味着调度器可以随时中断一个协程的执行,并将 CPU 时间片分配给另一个协程。

原理

Go语言的调度器是一个非常复杂的系统,但它的基本原理可以归结为以下几点:

  • 协程: 协程是 Go语言中的一种轻量级线程,它与线程的主要区别在于协程是由用户态代码管理的,而线程是由内核管理的。协程的创建和销毁都非常快速,这使得它非常适合于编写并发程序。
  • 操作系统线程: 操作系统线程是内核管理的执行单元,它可以独立地执行代码。每个协程都必须运行在一个操作系统线程上。
  • 调度器: 调度器负责将协程映射到操作系统线程上,并决定哪个协程应该在哪个线程上运行。调度器会根据协程的状态来做出决定,例如,如果一个协程正在等待 I/O 操作,那么调度器可能会将它从当前线程上移除,并将它放到另一个线程上运行。

工作原理

Go语言的调度器使用一种称为 M:N 调度的算法来管理协程和操作系统线程之间的关系。M:N 调度算法是指 M 个协程可以映射到 N 个操作系统线程上,其中 M 和 N 可以是任意正整数。

在 Go语言中,M 的值通常等于处理器的数量,而 N 的值可以根据需要进行调整。如果 N 的值大于 M 的值,那么就会出现协程并发的现象。

性能优化

为了提高 Go语言程序的性能,我们可以对调度器进行一些优化。以下是一些常见的优化技巧:

  • 减少协程的数量: 过多的协程会增加调度器的负担,从而降低程序的性能。因此,我们应该尽量减少协程的数量。
  • 避免协程阻塞: 协程阻塞是指协程在等待 I/O 操作或其他事件时无法继续执行。协程阻塞会导致调度器不得不将协程从当前线程上移除,并将它放到另一个线程上运行,这会增加调度器的负担。因此,我们应该尽量避免协程阻塞。
  • 使用合理的 N 值: N 的值应该根据程序的实际情况进行调整。如果 N 的值太小,那么就会出现协程并发的现象,这会降低程序的性能。如果 N 的值太大,那么就会浪费操作系统线程资源。

实战案例

在我们的一个工作项目中,我们使用 Go语言的调度器来实现了一个并发文件下载程序。该程序可以同时下载多个文件,并且可以自动重试下载失败的文件。

以下是该程序的部分代码:

package mainimport ("context""fmt""io""net/http""os""sync"
)// 定义一个协程安全的计数器
var wg sync.WaitGroup// 定义一个下载文件的函数
func downloadFile(ctx context.Context, url, filepath string) error {// 创建一个 HTTP 请求req, err := http.NewRequest("GET", url, nil)if err != nil {return err}// 发送 HTTP 请求resp, err := http.DefaultClient.Do(req)if err != nil {return err}defer resp.Body.Close()// 创建一个文件f, err := os.Create(filepath)if err != nil {return err}defer f.Close()// 将 HTTP 响应体复制到文件中_, err = io.Copy(f, resp.Body)if err != nil {return err}return nil
}// 定义一个主函数
func main() {// 创建一个 contextctx := context.Background()// 创建一个协程池pool := make(chan struct{}, 10)// 创建一个文件列表files := []string{"https://example.com/file1.txt","https://example.com/file2.txt","https://example.com/file3.txt",}// 遍历文件列表for _, file := range files {// 将协程池中的一个令牌消耗掉pool <- struct{}{}// 启动一个协程来下载文件go func(file string) {defer func() {// 将协程池中的一个令牌释放出来<-pool}()// 增加计数器的值wg.Add(1)// 下载文件err := downloadFile(ctx, file, "file/"+filepath.Base(file))if err != nil {fmt.Println(err)}// 减少计数器的值wg.Done()}(file)}// 等待所有协程执行完毕wg.Wait()
}

相关文章:

Go语言的调度器

简介 Go语言的调度器是一个非常强大的工具&#xff0c;它可以帮助我们轻松地实现并发编程。调度器的工作原理是将多个协程映射到多个操作系统线程上&#xff0c;并根据协程的状态来决定哪个协程应该在哪个线程上运行。 调度器有两种主要策略&#xff1a; 协作式调度&#xf…...

Linux系统使用超详细(十)~vi/vim命令①

vi/vim命令有很多&#xff0c;其实只有少数的用法对于我们日常工作中起到了很大帮助&#xff0c;但是既然我选择梳理Linux的学习笔记&#xff0c;那么一定全力把自己的理解和学习笔记的内容认真整理汇总&#xff0c;内容或许有错误&#xff0c;还请发现的C友们发现了及时指出。…...

C语言实现双向链表

1.版本一 由于节点之间的连接变多 所以我们最好提前将前驱节点和后继节点用变量保存下来 以免等下在进行节点之间的指向时出错 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> // 节点类 typedef struct Node {// 数据域int data;// 指针域…...

OpenGL 网格拾取坐标(Qt)

文章目录 一、简介二、代码实现三、实现效果参考资料一、简介 有时候我们希望通过鼠标来拾取某个网格中的坐标,这就涉及到一个很有趣的场景:光线投射,也就是求取一条射线与网格的交点,这里如果我们采用普通遍历网格中的每个面片的方式,当网格的面片数据量很大时计算效率就…...

GitHub高级搜索技巧

GitHub高级搜索技巧 in:name <关键字> 仓库名称带关键字查询 in:description <关键字> 仓库描述带关键字查询 in:readme <关键字> README文件带关键字查询 stars(fork): >() <数字> <关键字> star或fork数大于(或等于)指定数字的带关键字查…...

docker-compose安装HertzBeat赫兹跳动监控H3C交换机

前面我们用docker方式安装了HertzBeat&#xff0c;现在我们自己写个docker-compose.yml文件、创建文件直接docker-compose up -d直接启动运行 使用docker-compose需要先安装docker和docker-compose1、输入以下两段命令 mkdir 123 && cd 123 && mkdir data &a…...

NetSuite学习笔记 - 中心

一、什么是中心&#xff1f; 对于每个用户&#xff0c;NetSuite 会根据用户的指定角色显示一组可变的标签页面&#xff0c;称为中心。通俗来讲呢&#xff0c;NetSuite的中心其实就是我们常说的“导航菜单”。 只是在我过去常见的系统中&#xff0c;导航菜单一般都是固定的&am…...

鸿蒙开发笔记(三):页面和自定义组件生命周期

先明确自定义组件和页面的关系&#xff1a; 自定义组件&#xff1a;Component装饰的UI单元&#xff0c;可以组合多个系统组件实现UI的复用。 页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定义组件为页面的入口组件&#xff0c…...

报名活动怎么做_小程序创建线上报名活动最详细攻略

报名活动怎么做&#xff1a;一篇让你掌握活动策划与营销的秘籍 在当今社会&#xff0c;无论是线上还是线下&#xff0c;活动已经成为企业营销和品牌推广的重要手段。但是&#xff0c;如何策划一场成功的活动呢&#xff1f;这篇文章将为你揭示活动策划与营销的秘籍&#xff0c;…...

Apache POI 导出Excel报表

大家好我是苏麟 , 今天聊聊Apache POI . Apache POI 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下&#xff0c;POI 都是用于操作 E…...

使用Qt连接scrcpy-server控制手机

Qt连接scrcpy-server 测试环境如何启动scrcpy-server1. 连接设备2. 推送scrcpy-server到手机上3. 建立Adb隧道连接4. 启动服务5. 关闭服务 使用QTcpServer与scrcpy-server建立连接建立连接并视频推流完整流程1. 开启视频推流过程2. 关闭视频推流过程 视频流的解码1. 数据包协议…...

debian12部署Gitea服务之二——部署git-lfs

Debian安装gitlfs: 先更新下软件包版本 sudo apt update 安装 sudo apt install git-lfs 验证是否安装成功 git lfs version cd到Gitea仓库目录下 cd /mnt/HuHDD/Git/Gitea/Repo/hu/testrepo.git 执行lfs的初始化命令 git lfs install客户机Windows端在官网下载并安装Git-Lfs 再…...

leetcode 1两数之和

题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺…...

C++多线程学习[三]:成员函数作为线程入口

一、成员函数作为线程入口 #include<iostream> #include<thread> #include<string>using namespace std;class Mythread { public:string str;void Test(){cout << str << endl;} }; int main() {Mythread test;test.str "Test";thr…...

移动硬盘无法识别处理办法

今天这里做一下总结&#xff0c;我现在手上有一个移动硬盘&#xff0c;插入win10电脑是有盘号的&#xff0c;但是 但是点击就出问题 解决办法 安装DiskGenius 下载网址在https://www.diskgenius.cn/download.php 下载之后解压安装就行&#xff0c;非常简单&#xff0c;然后…...

【Spring Cloud】Sentinel流量限流和熔断降级的讲解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Cloud》。&#x1f3af;&#x1f3af; &am…...

前端浮点和16进制互转

一、浮点转16进制数据 //浮点数转16进制 function singleToHex(t) {if (t "") {return "";}t parseFloat(t.substr(0, 4));if (isNaN(t) true) {return "Error";}if (t 0) {return "00000000";}var s,e,m;if (t > 0) {s 0;}e…...

Java中hashCode()与equals()的相关规定

API文件有对对象的状态制定出必须遵循的规则。hashCode()和equals()是object中定义的两个方法&#xff0c;它们都与对象的相等性有关。 通常情况下我们需要同时使用这两个方法来判断两个对象是否相等&#xff0c;只有两个对象的equals()方法返回true&#xff0c;并且它们的has…...

转行做鸿蒙开发首先需要学习哪些?

随着越来越多的企业和团队开始布局鸿蒙生态&#xff0c;鸿蒙开发人才的需求也呈现出井喷式的增长。对于开发者而言&#xff0c;掌握鸿蒙开发技能不仅意味着能够抓住这个千载难逢的机遇&#xff0c;更意味着能够在未来的科技竞争中占据先机。 在这个变革的时代&#xff0c;鸿蒙开…...

8x8离散余弦的快速精确实现使用数据流单指令多数据扩展指令集进行转换MMX 说明书

1.https://www.cs.cmu.edu/~barbic/cs-740/ap922.pdf 2.FFmpeg: libavcodec/x86/fdct.c Source File 再学FDCT快速精确实现协议改写浮点FDCT, ffmpeg的dct使用的就是这个快速精确协议。 3.http://dspace.fcu.edu.tw/bitstream/2377/30265/1/ICM%204-1.pdf 我想如把所有余弦…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...