1.10 双线程高效下载

2024-05-15 16:08
文章标签 高效 下载 双线 1.10

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

(一)题目

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

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

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

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

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


代码如下:

class Thread {
public:Thread(void (*work_func)());~Thread();void Start();void Abort();
};class Semaphore {
public:Semaphore(int count, int max_count);~Semaphore();void Unsignal();   //count--void Signal();     //count++
};class Mutex {
public:WaitMutex();ReleaseMutex();
};//如果使用Mutex,下载和存储线程将不能同时工作,因此,Semaphore是更好的选择
#define BUFFER_COUNT 100
Block g_buffer[BUFFER_COUNT];Thread g_threadA(ProcA);
Thread g_threadB(ProcB);
Semaphore g_seFull(0, BUFFER_COUNT);    //一开始缓冲区无数据可供存储
Semaphore g_seEmpty(BUFFER_COUNT, BUFFER_COUNT); //一开始缓冲区空间为BUFFER_COUNT,整个缓冲区可供下载的数据填充bool g_downloadComplete;  //下载任务是否完成
int in_index = 0;    //下载的数据从缓冲区的哪个地方开始填充
int out_index = 0;   //存储的数据从缓冲区的哪个地方开始提取void main() {g_downloadComplete = false;g_threadA.Start();g_threadB.Start();
}void ProcA() {while(true) {g_seEmpty.Unsignal();   //首先取得一个空闲空间,以便下载数据填充g_downloadComplete = GetBlockFromNet(g_buffer + in_index);   //填充in_index = (in_index + 1) % BUFFER_COUNT;  //更新索引g_seFull.Signal();   //提示存储线程可以工作if(g_downloadComplete) break;   //当任务全部下载完成,进程就可以结束了}
}void ProcB() {while(true) {g_seFull.Unsignal();   //查询时候有数据可供存储WriteBlockToDisk(g_buffer + out_index);  //存储out_index = (out_index + 1) % BUFFER_COUNT;   //更新索引g_seEmpty.Signal();   //将空闲空间还给缓冲区if(g_downloadComplete && out_index == in_index) break;  //当任务全部下载完成,并且所有的数据都存储到硬盘中,进程才可以结束}
}


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



http://www.chinasem.cn/article/992282

相关文章

Java下载文件中文文件名乱码的解决方案(文件名包含很多%)

《Java下载文件中文文件名乱码的解决方案(文件名包含很多%)》Java下载文件时,文件名中文乱码问题通常是由于编码不正确导致的,使用`URLEncoder.encode(filepath,UTF-8... 目录Java下载文件中文文件名乱码问题一般情况下,大家都是这样为了解决这个问题最终解决总结Java下

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

Python利用自带模块实现屏幕像素高效操作

《Python利用自带模块实现屏幕像素高效操作》这篇文章主要为大家详细介绍了Python如何利用自带模块实现屏幕像素高效操作,文中的示例代码讲解详,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、获取屏幕放缩比例2、获取屏幕指定坐标处像素颜色3、一个简单的使用案例4、总结1、获取屏幕放缩比例from

Python实现文件下载、Cookie以及重定向的方法代码

《Python实现文件下载、Cookie以及重定向的方法代码》本文主要介绍了如何使用Python的requests模块进行网络请求操作,涵盖了从文件下载、Cookie处理到重定向与历史请求等多个方面,... 目录前言一、下载网络文件(一)基本步骤(二)分段下载大文件(三)常见问题二、requests模块处理

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用