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

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

相关文章

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Java高效实现PowerPoint转PDF的示例详解

《Java高效实现PowerPoint转PDF的示例详解》在日常开发或办公场景中,经常需要将PowerPoint演示文稿(PPT/PPTX)转换为PDF,本文将介绍从基础转换到高级设置的多种用法,大家... 目录为什么要将 PowerPoint 转换为 PDF安装 Spire.Presentation fo

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

使用SpringBoot+InfluxDB实现高效数据存储与查询

《使用SpringBoot+InfluxDB实现高效数据存储与查询》InfluxDB是一个开源的时间序列数据库,特别适合处理带有时间戳的监控数据、指标数据等,下面详细介绍如何在SpringBoot项目... 目录1、项目介绍2、 InfluxDB 介绍3、Spring Boot 配置 InfluxDB4、I

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

AOP编程的基本概念与idea编辑器的配合体验过程

《AOP编程的基本概念与idea编辑器的配合体验过程》文章简要介绍了AOP基础概念,包括Before/Around通知、PointCut切入点、Advice通知体、JoinPoint连接点等,说明它们... 目录BeforeAroundAdvise — 通知PointCut — 切入点Acpect — 切面

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图