1.10 编程之美-双线程下载[double threads to download]
2014-07-04 09:12
302 查看
【本文链接】
/article/5268978.html
【题目】
网络上下载数据,然后存储到硬盘上。简单做法是:先下载一块然后写到硬盘,然后再下载,再写到硬盘上。
缺点:需要先下载完才能写入硬盘,下载和写是串行操作。
改进:让两个线程并行进行,设置缓冲区,采用信号量的形式。
下载线程,只要缓冲区有空余就下载,下载完成之后告诉写线程缓冲区有数据了。
写线程,只要缓冲区有数据就写入,写完后告诉下载线程缓冲区有空闲了。
【代码】
C++ Code
【参考】
/article/6256094.html
/article/4744998.html
/article/1413049.html
【本文链接】
/article/5268978.html
/article/5268978.html
【题目】
网络上下载数据,然后存储到硬盘上。简单做法是:先下载一块然后写到硬盘,然后再下载,再写到硬盘上。
缺点:需要先下载完才能写入硬盘,下载和写是串行操作。
改进:让两个线程并行进行,设置缓冲区,采用信号量的形式。
下载线程,只要缓冲区有空余就下载,下载完成之后告诉写线程缓冲区有数据了。
写线程,只要缓冲区有数据就写入,写完后告诉下载线程缓冲区有空闲了。
【代码】
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | // /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/7/4 */ //---------------------API------------------------------ //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 disk bool 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 1000 //缓冲区数组,模拟循环队列 Block 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(); } |
/article/6256094.html
/article/4744998.html
/article/1413049.html
【本文链接】
/article/5268978.html
相关文章推荐
- [编程之美] PSet1.10 双线程高效下载
- 读书笔记之编程之美 - 1.10 双线程高效下载
- 用URLDownloadToFile下载文件
- URLDownloadToCacheFile,下载文件到缓存中
- UrlDownloadFile, 线程下载文件, 带进度条
- 原始线程(protothreads)
- C语言封装的轻量线程环境 Protothreads
- C++Builder利用URLDownloadToFile下载文件并显示进度
- Introduction to processes and threads(线程与进程的区别)
- 转:delphi用URLDownloadToFile下载文件,用进度条跟踪下载进度
- LInux高级编程 - 线程(Threads)
- 使用URLDownloadToFile下载文件,有进度
- UrlDownloadFile, 线程下载文件, 带进度条
- How to Download Embedded Flash Files using your Browser 从浏览器下载网页内嵌的Flash文件的方法
- UrlDownloadtoFile文件下载,进度条,下载暂停,停止的简单实现
- [编程之美]双线程高效下载
- 一个使用URLDownloadToFile实现文件下载的类
- vb URLDownloadToFile下载函数
- UrlDownloadToVar()函数-下载到变量
- URLDownloadToFile下载文件文章两篇