关于 Goroutines 和并发控制的 Golang 难题

news/2024/9/25 7:59:38/

下面是一道关于 Goroutines 和并发控制的 Golang 难题,它涉及到 Go 的并发编程模型、Goroutines、通道(Channels)以及 sync.WaitGroup 的使用:

问题描述:

你有一个需要并发执行的任务,其中有 100 个 URL 需要下载并处理。每个 URL 的下载和处理都是一个耗时的操作,且最多只能同时运行 5 个 Goroutine。每个 Goroutine 在处理完成后,应将结果(假设是下载的数据)传回主 Goroutine 进行汇总。

你需要:

  1. 实现一个并发下载的函数 downloadAndProcess,并确保在任何时刻都只有 5 个 Goroutine 同时运行。
  2. 所有下载任务完成后,主 Goroutine 要能够获取到每个 URL 对应的下载结果,并输出汇总后的总结果(例如所有 URL 的数据大小总和)。

要求:

  • 不能使用第三方库。
  • 需要用 sync.WaitGroup 和通道(Channel)来管理并发和数据传递。

提示:

  • 你可以使用 sync.WaitGroup 来等待所有 Goroutine 完成。
  • 使用一个带缓冲区的通道来限制并发的 Goroutine 数量(最多 5 个)。
  • 使用一个无缓冲的通道将下载的结果传递给主 Goroutine。

示例代码框架:

package mainimport ("fmt""sync"
)// downloadAndProcess 模拟下载并处理一个 URL 的函数
func downloadAndProcess(url string) int {// 假设这里是耗时操作,返回下载内容的长度// 实际应用中可以是 http.Get(url) 的结果长度return len(url)
}func main() {urls := []string{// 100 个不同的 URL 列表"http://example.com/1","http://example.com/2",// 省略其余 URL ...}var wg sync.WaitGroup// 结果通道,用于收集每个 URL 的下载结果results := make(chan int)// 并发限制,最多允许 5 个 Goroutine 并发运行concurrencyLimit := make(chan struct{}, 5)// 完成下载后,主 Goroutine 获取结果并汇总go func() {var totalSize intfor size := range results {totalSize += size}fmt.Println("所有 URL 下载完成,总大小:", totalSize)}()// 启动 Goroutines 来处理每个 URLfor _, url := range urls {wg.Add(1)go func(url string) {defer wg.Done()// 获取并发限制通道的许可concurrencyLimit <- struct{}{}// 模拟下载并处理 URLsize := downloadAndProcess(url)// 将结果发送到通道results <- size// 释放并发限制通道的许可<-concurrencyLimit}(url)}// 等待所有 Goroutine 完成wg.Wait()// 所有 Goroutine 完成后,关闭结果通道close(results)
}

难点分析:

  • Goroutine 限制:最多只能有 5 个 Goroutine 并发运行,需要利用带缓冲区的通道来实现。
  • 结果汇总:需要主 Goroutine 不断从通道中读取结果并累加,直到所有 Goroutine 都完成。
  • 同步控制:使用 sync.WaitGroup 确保主 Goroutine 在所有子 Goroutine 完成后关闭通道。

这道题考察了并发控制、通道的使用、Goroutine 限制和同步操作等关键并发编程知识。


http://www.ppmy.cn/news/1530191.html

相关文章

【赵渝强老师】K8s中的Deployment控制器

K8s的Deployment将Pod部署成无状态的应用程序&#xff0c;它只关心Pod的数量、Pod更新方式、使用的镜像和资源限制等。由于是无状态的管理方式&#xff0c;因此Deployment中没有角色和顺序的概念&#xff0c;换句话说&#xff1a;Deployment中没有状态。   通过使用Deploymen…

研究生第一次刷力扣day1

1.给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出和为目标值target 的那两个整数&#xff0c;并返回它们的数组下标 直接采用暴力求解&#xff0c;其他解答案看不懂 大致思想&#xff1a;先用len函数求出数组的长度n&#xff0c;然后一个个遍…

【大数据入门 | Hive】DDL数据定义语言(数据库DataBase)

1. 数据库(DataBase) 1.1 创建数据库 语法&#xff1a; CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_nameproperty_value, ...)]; 案例&#xff1a; &#xff08;1&#xff09;创建一个…

Linux Shell: 使用 Expect 自动化 SCP 和 SSH 连接的 Shell 脚本详解

文章目录 0. 引言2. 解决方案3. 脚本详解脚本1&#xff1a;使用 SSH 和 Expect 自动化登录远端机器脚本说明 脚本2&#xff1a;使用 SCP 和 Expect 自动化文件上传脚本说明 脚本3&#xff1a;使用 SCP 和 Expect 自动化文件下载脚本说明 4. 脚本的使用方法5. 关键技术点5.1. Ex…

PhpStudy | PHP 版本切换流程

关注这个软件的其他相关笔记&#xff1a;PhpStudy —— README-CSDN博客 在使用多样化的 PHP Web 应用程序时&#xff0c;选择合适的 PHP 版本至关重要。例如&#xff0c;一些老旧的应用程序可能是基于早期版本的 PHP 开发的&#xff0c;如果使用最新版本的 PHP 来运行&#xf…

从事新闻、出版、教育、药品和医疗器械、文化、广播电影电视节目等互联网信息服务小程序备案说明

根据《互联网信息服务管理办法》、《非经营性互联网信息服务备案管理办法》规定&#xff0c;从事新闻、出版、教育、药品和医疗器械、文化、广播电影电视节目等互联网信息服务&#xff0c;依照法律、行政法规以及国家有关规定须经有关主管部门审核同意的&#xff0c;在履行备案…

Android数据序列化总结

Android数据序列化总结 什么是序列化 序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间&#xff0c;对象将其当前状态写入到临时或持久性存储区。以后&#xff0c;可以通过从存储区中读取或反序列化对象的状态&#xff0c;重新创建该对…

【网络底层原理】I/O多路复用技术select、poll和epoll详解与比较

引言 在现代网络编程中&#xff0c;I/O多路复用技术是实现高性能服务器的关键。本文将详细介绍select、poll和epoll这三种技术&#xff0c;并比较它们的工作原理、优势与限制。 1. select 工作原理 select技术使用三个集合&#xff08;读、写、异常&#xff09;来跟踪需要监…