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.