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

news/2024/9/20 12:15:47 标签: golang, ios, 数据库

下面是一道关于 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 main

import (
	"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 int
		for size := range results {
			totalSize += size
		}
		fmt.Println("所有 URL 下载完成,总大小:", totalSize)
	}()

	// 启动 Goroutines 来处理每个 URL
	for _, url := range urls {
		wg.Add(1)
		go func(url string) {
			defer wg.Done()

			// 获取并发限制通道的许可
			concurrencyLimit <- struct{}{}

			// 模拟下载并处理 URL
			size := downloadAndProcess(url)

			// 将结果发送到通道
			results <- size

			// 释放并发限制通道的许可
			<-concurrencyLimit
		}(url)
	}

	// 等待所有 Goroutine 完成
	wg.Wait()

	// 所有 Goroutine 完成后,关闭结果通道
	close(results)
}

难点分析:

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

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


http://www.niftyadmin.cn/n/5667091.html

相关文章

MATLAB 图像处理入门详解

图像处理在现代科学、工业、医学等领域扮演着至关重要的角色,而 MATLAB 作为强大的数学计算平台,在图像处理方面具有丰富的函数库和工具箱。本文将为大家详细介绍 MATLAB 中图像处理的基础知识,帮助读者从零开始掌握 MATLAB 图像处理的相关技能。 一、什么是图像处理? 图…

python 绘制 y=x^3 图像

python 绘制 yx^3 图像 import numpy as np -----------------激活numpy import matplotlib.pyplot as plt -------------------激活matplotlib xnp.arange(-10,10,0.01) ---------------------设置x的取值范围&#xff0c;设置坐标值 yx*x*x ------…

计算机毕业设计hadoop+spark知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习

《HadoopSpark知网文献论文推荐系统》开题报告 一、研究背景及意义 随着互联网技术的迅猛发展和大数据时代的到来&#xff0c;学术文献的数量呈爆炸式增长&#xff0c;用户面临着严重的信息过载问题。如何高效地从海量文献中筛选出用户感兴趣的论文&#xff0c;成为当前学术界…

JAVA零基础入门——面向对象

1.继承 1.1 继承概念 继承的概念&#xff1a;继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父类相同的行为。我们将"继承概念"分为两类:…

Tomcat 8 配置80端口直接访问并配置默认项目

一、配置80端口访问 打开你的 Tomcat 安装目录&#xff0c;打开【conf】文件的【server.xml】&#xff0c;找到如下内容&#xff1a; <Connector port"8080" redirectPort"8443" connectionTimeout"20000" protocol"HTTP/1.1"/&g…

【PyTorch】深入浅出PyTorch

为什么要学习PyTorch Why learn PyTorch PyTorch日益增长的发展速度与深度学习时代的迫切需求 PyTorch实验模型训练 数据 模型 损失函数 优化器 迭代训练 模型应用 如何学习和掌握PyTorch 勤动手 成体系 构建知识体系 熟悉知识分布 对应查缺补漏 多总结

win11下面的virtualenv的使用(没写完)

安装命令 pip install virtualenv pip install virtualenv-win 控制面板-Administrator环境变量配置 VIRTUALENV_CONFIG_FILEE:\ENVS\virtualenv.ini Powershell设置 一、Powershell终端输入下列命令 Test-Path $profile New-Item -path $profile -type file –force 上…

DorisManager使用

Release Notes&#xff1a; 发布日期&#xff1a;2024 年 9 月 13 日 版本号&#xff1a;24.0.4-rc01 1、优化 Manager 在数据库升级或者 FE 重启时&#xff0c;应当检测 FE 的时间同步服务的问题 2、修复升级前置中目录权限检查的问题 3、修复扩容时部署目录不以 FE 结尾则找不…