您的位置:首页 > 编程语言 > C语言/C++

C++: 对双线程下载程序的封装和模拟

2010-04-22 12:17 316 查看
这是主程序,其中:

对线程,信号量进行了windows API的封装;

类似还可以完成对Mutex互斥量,临界区等的封装工作.

//main.cpp

#include <iostream>
#include <windows.h>
#include "helper.h"
using namespace std;

/************************************************************************/
/* Thread                                                               */
/************************************************************************/

typedef DWORD (WINAPI *ThreadProc)(LPVOID lpParameter);

class Thread
{
HANDLE hThread;
DWORD dwThreadId;
public:
Thread(ThreadProc func)
{
dwThreadId = -1;
hThread = NULL;
hThread = CreateThread(NULL, 0, func, 0, CREATE_SUSPENDED, &dwThreadId);
if(hThread == NULL)
cout << "Create thread error: " << GetLastError() << endl;
}

DWORD getThreadId()
{
return dwThreadId;
}

HANDLE getThread()
{
return hThread;
}

void start()
{
ResumeThread(hThread);
}

void abort()
{
SuspendThread(hThread);
}

~Thread()
{
CloseHandle(hThread);
}
};

/************************************************************************/
/* Semaphore                                                            */
/************************************************************************/
class Semaphore
{
HANDLE hSemaphore;
public:
Semaphore(int count, int nMaxCount)
{
hSemaphore = CreateSemaphore(NULL, count, nMaxCount, NULL); //无名信号量
}

//comsume a signal: count--
void unSignal()
{
WaitForSingleObject(hSemaphore, INFINITE);
}

//raise a signal: count++
void signal()
{
if(!ReleaseSemaphore(hSemaphore, 1, NULL))
cout << "Release semaphore error: " << GetLastError() << endl;
}

~Semaphore()
{
CloseHandle(hSemaphore);
}
};

/************************************************************************/
/* global defination                                                    */
/************************************************************************/
#define MAX_COUNT 100
int g_buffer[MAX_COUNT];

Semaphore g_seEmpty(MAX_COUNT, MAX_COUNT);
Semaphore g_seFull(0, MAX_COUNT);

int g_nInIndex = 0;
int g_nOutIndex = 0;
bool isDownloaded = false;

/************************************************************************/
/* thread proc                                                          */
/************************************************************************/
DWORD WINAPI downloadProc(LPVOID lpParameter)
{
while (true)
{
g_seEmpty.unSignal();
isDownloaded = getBlockFromNet(g_buffer+g_nInIndex);
g_nInIndex = (g_nInIndex+1)%MAX_COUNT;
g_seFull.signal();
if(isDownloaded)
break;
}
return 0L;
}

DWORD WINAPI writeProc(LPVOID lpParameter)
{
while (true)
{
g_seFull.unSignal();
writeBlockToDisk(g_buffer+g_nOutIndex);
g_nOutIndex = (g_nOutIndex+1)%MAX_COUNT;
g_seEmpty.signal();

if(isDownloaded && g_nInIndex == g_nOutIndex)
break;
}
return 0L;
}
int main()
{
prepareData();

Thread thDownload(downloadProc);
Thread thMove(writeProc);

thDownload.start();
thMove.start();

HANDLE arrHandles[] = {thDownload.getThread(), thMove.getThread()};
WaitForMultipleObjects(sizeof(arrHandles)/sizeof(HANDLE), arrHandles, TRUE, INFINITE);

destroyData();
return 0;
}


这是辅助程序, 其中:

getBlockFromNet函数, 我是直接从内存中读取来模拟的;

writeBlockToDisk函数, 我是把上述数据写到文件中来实现的.

大致是可以模拟出来的.

//helper.h

#include <fstream>
#include <iostream>
using namespace std;

#define MAX_BUFFER 10000
int buffer[MAX_BUFFER];
int index = 0;
ofstream ofs;

void prepareData()
{
ofs.open("e://out.txt");
for (int i = 0; i < MAX_BUFFER; ++i)
buffer[i] = i;
}

bool getBlockFromNet(int* buf)
{
*buf = buffer[index++];
if(index < MAX_BUFFER)
return false;
else
return true; //取得最后一个buffer[MAX_BUFFER-1], 并返回true
}

void writeBlockToDisk(int* buf)
{
ofs << *buf << " ";
}

void destroyData()
{
ofs.close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: