简体   繁体   中英

Manage shared variable in multithreading application

I designed one sample multithreaded application in which I read one file in one thread using circular buffer with checking isfull or not, also write same buffer to output file with checking buffer isEmpty or not.

My problem is that first thread complete its execution first so that second thread gets remaining data in buffer, so output is wrong.

Code:

 /* Circular Queues */
//#include<mutex.h>
#include <iostream>
using namespace std;
#include<windows.h>

const int chunk = 512;      //buffer read data 
const int MAX = 2*chunk ;   //queue size
unsigned int Size ;
FILE *fpOut;
FILE *fp=fopen("Test_1K.txt","rb");

//class queue 
class cqueue
{
    public :
        static int front,rear;
        static char *a;
       cqueue()
       {
         front=rear=-1;
         a=new char[MAX];
       }
       ~cqueue()
       {
        delete[] a;
       }
};

int cqueue::front;
int cqueue::rear;
char* cqueue::a;

DWORD WINAPI Thread1(LPVOID param)
{   
    int i;

    fseek(fp,0,SEEK_END);
    Size=ftell(fp);             //Read file size
    cout<<"\nsize is"<<Size;
    rewind(fp);

    for(i=0;i<Size;i+=chunk)    //read data in chunk as buffer half size 
    {
        while((cqueue::rear==MAX-1)); //wait until buffer is full?
            if((cqueue::rear>MAX-1))        
              cqueue::rear=0;       
           else{
               fread(cqueue::a,1,chunk,fp); //read data from in buffer
                cqueue::rear+=chunk;        //increment rear pointer of queue to indicate buffer is filled up with data
                 if((cqueue::front==-1))    
                    cqueue::front=0;        //update front pointer value to read data from buffer in Thread2
           } 
    }
    fclose(fp);
    cout<<"\nQueue write completed\n";
    return 0;
}
DWORD WINAPI Thread2(LPVOID param)
{
    for(int j=0;j<Size;j+=chunk)
    {
        while((cqueue::front==-1)); //wait until buffer is empty
        cqueue::front+=chunk;       //update front pointer after read data from queue
        fwrite(cqueue::a,1,chunk,fpOut);    //write data file

       if((cqueue::front==MAX-1))
          cqueue::front=0;      //update queue front pointer when it reads upto queue Max size
    }
    fclose(fpOut);
    cout<<"\nQueue read completed\n";
    return 0;
}


void startThreads()
{
    DWORD  threadIDs[2];
    HANDLE threads[2];  
    fpOut=fopen("V-1.7OutFile.txt","wb");
    threads[0] = CreateThread(NULL,0,Thread1,NULL,0,&threadIDs[0]);
    threads[1] = CreateThread(NULL,0,Thread2,NULL,0,&threadIDs[1]); 

    if(threads[0] && threads[1])
    {
        printf("Threads Created.(IDs %d and %d)",threadIDs[0],threadIDs[1]);
    }
}

void main()
{
     cqueue c1;
     startThreads();
     system("pause");
}

Please suggest any solution for shared buffer accessing.

A major problem here is that you use static member variable, but never initialize them except in the constructor, and as you never actually construct an instance of the class the constructor will not be called.

That means when you use the static member variables they contain indeterminate values (ie their values will be seemingly random) you invoke undefined behavior .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM