CFGReader

Practice for multi-thread(1)

    A. First Edition

    I am practicing with multi-thread.

    B.The problem

กก

C.The idea of program
กก

    A kind of combination of reader-writer and bounded-buffer problem.

    D.The major functions

    E.Further improvement

    F.File listing

    1. main.cpp (main)

    กก

    กก

    file name: main.h

    #include <iostream>
    #include <windows.h>

    using namespace std;

    #define FileOpenError 1

    const int ReadingLength=20;
    const int WritingLength=80;
    const int MaxThreadCount=5;
    const char* inFileNames[MaxThreadCount-1] =
    {
    	"c:\\inputFile1.txt",
    	"c:\\inputFile2.txt",
    	"c:\\inputFile3.txt",
    	"c:\\inputFile4.txt"
    };

    const char* outFileName= "c:\\outputFile.txt";
    const int MaxBufferLength=256;

    int front=0;
    int rear=0;
    int counter=0;

    HANDLE threads[MaxThreadCount];

    int threadIndex[MaxThreadCount]={0,1,2,3,4};

    bool finished[MaxThreadCount]={false};

    FILE *in[MaxThreadCount-1], *out;

    char buffer[MaxBufferLength];

    DWORD WINAPI run(void* param);

    void doWriting(int tid);
    void doReading(int tid);
    bool isFull();
    bool isEmpty();

    HANDLE sems[MaxThreadCount];

    int main()
    {
    	for (int i=0; i<MaxThreadCount-1; i++)
    	{
    		if ((in[i]=fopen(inFileNames[i], "r"))==NULL)
    		{
    			cout<<"unable to open file "<<inFileNames[i]<<endl;
    			exit(FileOpenError);
    		}
    	}

    	if ((out=fopen(outFileName, "w"))==NULL)
    	{
    		cout<<"unable to open output file "<<outFileName<<endl;
    		exit(FileOpenError);
    	}

    	for (i=0; i<MaxThreadCount; i++)
    	{
    		threads[i]=CreateThread(NULL, 0, run, threadIndex+i, CREATE_SUSPENDED, NULL);
    		sems[i]=CreateSemaphore(NULL, 0, 1, NULL);
    	}

    	cout<<"Now begin run...\n";
    	ReleaseSemaphore(sems[4], 1, NULL);
    	for (i=0; i<MaxThreadCount; i++)
    	{
    		ResumeThread(threads[i]);
    	}
    	bool canRun=true, flag;
    	while (canRun)
    	{
    		flag=true;
    		for (int i=0; i<MaxThreadCount; i++)
    		{
    			if (!finished[i])
    			{
    				flag=false;
    				break;
    			}
    		}
    		canRun=!flag;
    	}
    	//fputc(0, out);
    	//fclose(out);

    	return 0;
    }

    bool isFull()
    {
    	return (front+1)%MaxBufferLength==rear;
    }

    bool isEmpty()
    {
    	return front==rear;
    }

    void doWriting(int tid)
    {
    	if (isEmpty())
    	{
    		return;
    	}

    	if (counter==15)
    	{
    		for (int i=0; i<MaxThreadCount; i++)
    		{
    			finished[i]=true;
    		}
    	}
    	for (; (front-rear)%MaxBufferLength>0; ++rear%=MaxBufferLength)
    	{
    		fputc(buffer[(rear+1)%MaxBufferLength], out);
    	}
    	ReleaseSemaphore(sems[4], 1, NULL);
    	counter++;
    }

    void doReading(int tid)
    {
    	for (int i=0; i<ReadingLength; i++)
    	{
    		if (isFull())
    		{
    			break;
    		}
    		buffer[++front%=MaxBufferLength]=fgetc(in[tid-1]);
    	}
    	ReleaseSemaphore(sems[tid-1], 1, NULL);
    }

    DWORD WINAPI run(void* param)
    {
    	while (true)
    	{
    		WaitForSingleObject(sems[*((int*)(param))], INFINITE);
    		if (*((int*)(param))==0)
    		{
    			doWriting(*((int*)(param)));
    		}
    		else
    		{
    			doReading(*((int*)(param)));
    		}
    		if (finished[*((int*)(param))])
    		{
    			break;
    		}
    	}
    	return *((int*)(param));
    }

    The input is something like following:

    The input file is 4 files:

    this is input file 1this is input file 1this is input file 1....

    this is input file 2this is input file 2this is input file 2this is input file 2...

    this is input file 3this is input file 3this is input file 3this is input file 3...

    this is input file 4this is input file 4this is input file 4this is input file 4this is input file 4...

    Here is the result:

this is input file 4this is input file 3this is input file 2this is input file 1this is input file 4this is input file 3this is input file 2this is input file 1this is input file 4this is input file 3this is input file 2this is input file 1