【编程之美】双线程高效下载

2024-04-05 01:32

本文主要是介绍【编程之美】双线程高效下载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,题目

        网络上下载数据,然后存储到硬盘上。简单做法是:先下载一块然后写到硬盘,然后再下载,再写到硬盘上。

        缺点:需要先下载完才能写入硬盘,下载和写是串行操作。

        改进:让两个线程并行进行,设置缓冲区,采用信号量的形式。

                    下载线程,只要缓冲区有空余就下载,下载完成之后告诉写线程缓冲区有数据了。

                     写线程,只要缓冲区有数据就写入,写完后告诉下载线程缓冲区有空闲了。

        

二,核心源码


 //downloads a block from Internet sequentially in each call//return true, if the entire file is downloaded, otherwise false.bool GetBlockFromNet(Block* out_block);//writes a block to hard diskbool WriteBlockToDisk(Block* in_block);class Thread{public:Thread(void (*work_func)());~Thread();void Start();void Abort();};class Semaphore{public:Semaphore(int count,int max_count);~Semaphore();void Unsignal();void Signal();};class Mutex{public:WaitMutex();ReleaseMutex();};//----------------------------------------------------//1.确定使用信号量,而非互斥量,保证并行操作//2.当缓冲区并不满并且下载没结束时,下载线程运行//3.当缓冲区并不空并且下载没结束时,存储线程运行#define MAX_COUNT 1000Block g_Buffer[MAX_COUNT]; //缓冲区数组,模拟循环队列Thread g_Download(ProcA);Thread g_Write(ProcB);//一开始缓冲区空间为MAX_COUNT,整个缓冲区可供下载的数据填充Semaphore ForDownload(MAX_COUNT,MAX_COUNT);//一开始缓冲区无数据可供存储Semaphore ForWrite(0,MAX_COUNT);//下载任务是否完成bool isDone;//下载的数据从缓冲区的哪个地方开始填充int in_index;//存储的数据从缓冲区的哪个地方开始提取int out_index;void ProcA()//下载线程 {while(true){//首先取得一个空闲空间,以便下载数据填充ForDownload.Unsignal();//填充isDone=GetBlockFromNet(g_Buffer+in_index);//更新索引in_index=(in_index+1)%MAX_COUNT;//提示存储线程可以工作ForWrite.Signal();//当任务全部下载完成,进程就可以结束了if(isDone)break;}}void ProcB()//写入线程 {while(true){//查询时候有数据可供存储ForWrite.Unsignal();//存储WriteBlockToDisk(g_Buffer+out_index);//更新索引out_index=(out_index+1)%MAX_COUNT;//将空闲空间还给缓冲区ForDownload.Signal();//当任务全部下载完成,并且所有的数据都存储到硬盘中,进程才可以结束if(isDone&&in_index==out_index)break;}}int main(){isDone=false;in_index=0;out_index=0;g_Download.Start();g_Write.Start();}




这篇关于【编程之美】双线程高效下载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/877329

相关文章

Python Pandas高效处理Excel数据完整指南

《PythonPandas高效处理Excel数据完整指南》在数据驱动的时代,Excel仍是大量企业存储核心数据的工具,Python的Pandas库凭借其向量化计算、内存优化和丰富的数据处理接口,成为... 目录一、环境搭建与数据读取1.1 基础环境配置1.2 数据高效载入技巧二、数据清洗核心战术2.1 缺失

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

使用Python和SQLAlchemy实现高效的邮件发送系统

《使用Python和SQLAlchemy实现高效的邮件发送系统》在现代Web应用中,邮件通知是不可或缺的功能之一,无论是订单确认、文件处理结果通知,还是系统告警,邮件都是最常用的通信方式之一,本文将详... 目录引言1. 需求分析2. 数据库设计2.1 User 表(存储用户信息)2.2 CustomerO

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

MySQL重复数据处理的七种高效方法

《MySQL重复数据处理的七种高效方法》你是不是也曾遇到过这样的烦恼:明明系统测试时一切正常,上线后却频频出现重复数据,大批量导数据时,总有那么几条不听话的记录导致整个事务莫名回滚,今天,我就跟大家分... 目录1. 重复数据插入问题分析1.1 问题本质1.2 常见场景图2. 基础解决方案:使用异常捕获3.

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元