编程之美 1.10双线程高效下载
假设提供了以下方法:
bool GetBlockFromNet(Block *out_block);
bool WriteBlockToDisk(Block *in_block);
想实现高效当然是创建两个线程,A负责获取网络数据,B负责写入数据到硬盘,难点在于如何合理分配两个线程之间的工作!
分析与解法:
1.什么时候才算完成任务?
下载完毕并且完全存储到硬盘上,两个线程才能正常终止。
2.希望两个线程能同时工作,又不发生冲突,用什么方法?
使用Mutex(互斥量),下载时不能存储所以弃用。
使用Semaphore(信号量)是更好的选择。
3.下载与存储的必要条件
buffer满的时候和所有内容下载完毕,应该停止下载。
buffer为空时,没必要运行存储线程。
伪代码如下:
#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); bool g_downloadComplete; int in_index=0; int out_index=0; void main() { g_downloadComplete =false; g_threadA.Start(); g_threadA.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; } }