下载和写并行
线程A:从网络中读取一个数据块,存储到内存的缓存中。
线程B:从缓存中读取内容,存储到文件中。
多线程API
#pragma once
class Thread
{
public:
//initialize a thread and set the work function
Thread(void(*work_func)());
//once the object is destructed, the thread will be aborted
~Thread();
//start the thread
void Start();
//stop the thread
void Abort();
};
class Semaphore
{
public:
//initialize semaphore counts
Semaphore(int count, int max_count);
~Semaphore();
//consume a signal (count--),block current thread if count==0
void Unsignal();
//raise a signal (count++)
void Signal();
};
class Mutex
{
public:
//block thread until other threads relase the mutex
WaitMutex();
//relase mutex to let other thread wait for it
ReleaseMutex();
};
为了提高效率,希望两个线程能尽可能地同时工作。
如果使用Mutex,下载和存储线程将不能同时工作。因此,Semaphore 是更好的选择。
共享缓存区的数据结构
先下载的内容要先存储,这样才能保证内容的正确顺序。先进先出的典型数据结构是队列。因为我们采用了固定的缓冲空间来保存下载的内容,所以选择循环队列作为共享缓存区的数据结构。
#include "threads.h"
#define BUFFER_COUNT 100
Block g_buffer[BUFFER_COUNT];
Thread threadA(ProcA);
Thread 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;
threadA.Start();
threadB.Start();
// wait here till threads finished
}
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;
}
}
Index speed is reduced while you are using the computer.