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

来源:互联网 发布:数据库 oltp olap 编辑:程序博客网 时间:2024/05/21 18:48

这是主程序,其中:

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

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

[cpp] view plaincopy
  1. //main.cpp  
  2.   
  3. #include <iostream>  
  4. #include <windows.h>  
  5. #include "helper.h"  
  6. using namespace std;  
  7.   
  8. /************************************************************************/  
  9. /* Thread                                                               */  
  10. /************************************************************************/  
  11.   
  12. typedef DWORD (WINAPI *ThreadProc)(LPVOID lpParameter);  
  13.   
  14. class Thread  
  15. {  
  16.     HANDLE hThread;  
  17.     DWORD dwThreadId;  
  18. public:  
  19.     Thread(ThreadProc func)  
  20.     {  
  21.         dwThreadId = -1;  
  22.         hThread = NULL;  
  23.             hThread = CreateThread(NULL, 0, func, 0, CREATE_SUSPENDED, &dwThreadId);  
  24.             if(hThread == NULL)  
  25.                 cout << "Create thread error: " << GetLastError() << endl;  
  26.     }  
  27.   
  28.     DWORD getThreadId()  
  29.     {  
  30.         return dwThreadId;  
  31.     }  
  32.   
  33.     HANDLE getThread()  
  34.     {  
  35.         return hThread;  
  36.     }  
  37.   
  38.     void start()  
  39.     {  
  40.         ResumeThread(hThread);  
  41.     }  
  42.   
  43.     void abort()  
  44.     {  
  45.         SuspendThread(hThread);  
  46.     }  
  47.   
  48.     ~Thread()  
  49.     {  
  50.         CloseHandle(hThread);  
  51.     }  
  52. };  
  53.   
  54. /************************************************************************/  
  55. /* Semaphore                                                            */  
  56. /************************************************************************/  
  57. class Semaphore  
  58. {  
  59.     HANDLE hSemaphore;  
  60. public:  
  61.     Semaphore(int count, int nMaxCount)  
  62.     {  
  63.         hSemaphore = CreateSemaphore(NULL, count, nMaxCount, NULL); //无名信号量  
  64.     }  
  65.   
  66.     //comsume a signal: count--  
  67.     void unSignal()  
  68.     {  
  69.         WaitForSingleObject(hSemaphore, INFINITE);  
  70.     }  
  71.   
  72.     //raise a signal: count++  
  73.     void signal()  
  74.     {  
  75.         if(!ReleaseSemaphore(hSemaphore, 1, NULL))  
  76.             cout << "Release semaphore error: " << GetLastError() << endl;  
  77.     }  
  78.   
  79.     ~Semaphore()  
  80.     {  
  81.         CloseHandle(hSemaphore);  
  82.     }  
  83. };  
  84.   
  85. /************************************************************************/  
  86. /* global defination                                                    */  
  87. /************************************************************************/  
  88. #define MAX_COUNT 100  
  89. int g_buffer[MAX_COUNT];  
  90.   
  91. Semaphore g_seEmpty(MAX_COUNT, MAX_COUNT);  
  92. Semaphore g_seFull(0, MAX_COUNT);  
  93.   
  94. int g_nInIndex = 0;  
  95. int g_nOutIndex = 0;  
  96. bool isDownloaded = false;  
  97.   
  98. /************************************************************************/  
  99. /* thread proc                                                          */  
  100. /************************************************************************/  
  101. DWORD WINAPI downloadProc(LPVOID lpParameter)  
  102. {  
  103.     while (true)  
  104.     {  
  105.         g_seEmpty.unSignal();  
  106.         isDownloaded = getBlockFromNet(g_buffer+g_nInIndex);  
  107.         g_nInIndex = (g_nInIndex+1)%MAX_COUNT;  
  108.         g_seFull.signal();  
  109.         if(isDownloaded)  
  110.             break;  
  111.     }  
  112.     return 0L;  
  113. }  
  114.   
  115. DWORD WINAPI writeProc(LPVOID lpParameter)  
  116. {  
  117.     while (true)  
  118.     {  
  119.         g_seFull.unSignal();  
  120.         writeBlockToDisk(g_buffer+g_nOutIndex);  
  121.         g_nOutIndex = (g_nOutIndex+1)%MAX_COUNT;  
  122.         g_seEmpty.signal();  
  123.   
  124.         if(isDownloaded && g_nInIndex == g_nOutIndex)  
  125.             break;  
  126.     }  
  127.     return 0L;  
  128. }  
  129. int main()  
  130. {  
  131.     prepareData();  
  132.   
  133.     Thread thDownload(downloadProc);  
  134.     Thread thMove(writeProc);  
  135.   
  136.     thDownload.start();  
  137.     thMove.start();  
  138.   
  139.     HANDLE arrHandles[] = {thDownload.getThread(), thMove.getThread()};  
  140.     WaitForMultipleObjects(sizeof(arrHandles)/sizeof(HANDLE), arrHandles, TRUE, INFINITE);  
  141.   
  142.     destroyData();  
  143.     return 0;  
  144. }  

 

这是辅助程序, 其中:

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

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

大致是可以模拟出来的.

[cpp] view plaincopy
  1. //helper.h  
  2.   
  3. #include <fstream>  
  4. #include <iostream>  
  5. using namespace std;  
  6.   
  7. #define MAX_BUFFER 10000  
  8. int buffer[MAX_BUFFER];  
  9. int index = 0;  
  10. ofstream ofs;  
  11.   
  12. void prepareData()  
  13. {  
  14.     ofs.open("e://out.txt");  
  15.     for (int i = 0; i < MAX_BUFFER; ++i)  
  16.         buffer[i] = i;  
  17. }  
  18.   
  19. bool getBlockFromNet(int* buf)  
  20. {  
  21.     *buf = buffer[index++];  
  22.     if(index < MAX_BUFFER)  
  23.         return false;  
  24.     else  
  25.         return true//取得最后一个buffer[MAX_BUFFER-1], 并返回true  
  26. }  
  27.   
  28. void writeBlockToDisk(int* buf)  
  29. {  
  30.     ofs << *buf << " ";  
  31. }  
  32.   
  33. void destroyData()  
  34. {  
  35.     ofs.close();  
  36. }