下载和写并行

线程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.

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐