利用生产者(读)消费者(写)模型拷贝大文件

来源:互联网 发布:ipadair2不能下载软件 编辑:程序博客网 时间:2024/06/10 23:36
#include <iostream>
#include <windows.h>
#include <deque>


#define nComsers 3
#define nLenth 4*1024
HANDLE g_hProducer;
HANDLE g_hComsuers[nComsers];
HANDLE g_hFullSemaphore;
HANDLE g_hEmptySemaphore;
HANDLE g_hMutex;




DWORD WINAPI ProducerProc(LPVOID); 
DWORD WINAPI ConsumersProc(LPVOID);


const char* SourceFilePath = "D:\\temp.txt";
const char* CopyFilePath = "D:\\copytemp.txt";


typedef struct BUF 
{
char buff[nLenth];
}buffer;
std::deque<buffer> mem_deque;


void CreateProducer()
{
g_hProducer = CreateThread(NULL, 0, ProducerProc, NULL, 0, NULL);
CloseHandle( g_hProducer );
}
void CreateConsumers()
{
for ( int i = 0; i < nComsers; i++ )
{
g_hComsuers[i] = CreateThread(NULL, 0, ConsumersProc, (LPVOID)(i+1), 0, NULL);
CloseHandle(g_hComsuers[i]);
}
}
int main()
{
//最大信号量
const int NumSemaphore = 10;
g_hMutex = CreateMutex(NULL, false, NULL);


g_hFullSemaphore=CreateSemaphore(NULL,0,NumSemaphore,NULL);
g_hEmptySemaphore=CreateSemaphore(NULL,1,NumSemaphore,NULL);
CreateProducer();
CreateConsumers();
std::cout << "请稍等……" << std::endl;
//如果机器性能很差,Sleep时间可以适当延长
Sleep(10000);
CloseHandle(g_hFullSemaphore);
CloseHandle(g_hEmptySemaphore);
return 0;
}


//生产者
DWORD WINAPI ProducerProc(LPVOID)
{
FILE* fp_read = fopen(SourceFilePath, "r");
fseek(fp_read,0L,SEEK_END);
int nSize = ftell(fp_read);
fseek(fp_read,0L,SEEK_SET);
int nCount = 0;
int nRes = 0;
while(1)
{
WaitForSingleObject(g_hEmptySemaphore,INFINITE);

buffer nBuffer;
memset( nBuffer.buff, 0, nLenth);
if ( nCount == nSize/(nLenth-1) )
{
nRes = fread(nBuffer.buff, 1, nSize%(nLenth-1), fp_read);
*(nBuffer.buff+nRes) = '\0';
}else
{
nRes = fread(nBuffer.buff, 1, nLenth-1, fp_read);
*(nBuffer.buff+nRes) = '\0';
}
//std::cout << strlen(nBuffer.buff) << std::endl;


mem_deque.push_back( nBuffer );
nCount++;
if ( nRes != nLenth-1 )
{
//fflush(fp_read);
ReleaseSemaphore(g_hFullSemaphore, 1 ,NULL);
break;
}
ReleaseSemaphore(g_hFullSemaphore, 1 ,NULL);
}
fclose(fp_read);
return 0;
}
//消费者
FILE* fp_write = fopen(CopyFilePath, "a+");
int nRes = 0;
DWORD WINAPI ConsumersProc(LPVOID param)
{
while (1)
{
WaitForSingleObject(g_hFullSemaphore,INFINITE);
WaitForSingleObject( g_hMutex, INFINITE );


buffer nCopyBuffer = mem_deque.front();
mem_deque.pop_back();
nRes = fwrite(nCopyBuffer.buff, 1, strlen(nCopyBuffer.buff), fp_write);
if ( nRes != nLenth-1 )
{
fflush(fp_write);
break;
}
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);
}
fclose(fp_write);
return 0;
}