标签:style color 使用 ar 数据 sp art on 代码
(一)题目
网络上下载数据,然后存储到硬盘上。简单做法是:先下载一块然后写到硬盘,然后再下载,再写到硬盘上。
缺点:需要先下载完才能写入硬盘,下载和写是串行操作。
改进:让两个线程并行进行,设置缓冲区,采用信号量的形式。
下载线程,只要缓冲区有空余就下载,下载完成之后告诉写线程缓冲区有数据了。
写线程,只要缓冲区有数据就写入,写完后告诉下载线程缓冲区有空闲了。
代码如下:
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; //当任务全部下载完成,并且所有的数据都存储到硬盘中,进程才可以结束 } }
标签:style color 使用 ar 数据 sp art on 代码
原文地址:http://blog.csdn.net/u010470972/article/details/39899453