Click here to Skip to main content
16,016,623 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I design 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.So problem is that first thread complete it's execution first so that second thread gets remaining data in buffer,so output is wrong.Below i paste code of mine application,please check it & suggest any solution for shared buffer accessing.
C++
 /* Circular Queues */

#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");
}
Posted

Shared memory is a better solution, because you avoid disk access and its problems.

try it out:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx[^]

PS: writing a file in the directory of the app is always a bad idea
 
Share this answer
 
You describe classic Producer-Consumer problem.

[]http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem[^]

Regarding queue that you implemented - much better solution is to encapsulate queue operations in the queue class, and make internal queue data private.

Another option - just use < queue > STL.
 
Share this answer
 
In addition to what has been said in other solutions, you need to use some synchronisation mechanism (lock, semaphore, mutex) or concurrent containers or some lock-free container.

In particular, the line
C++
while((cqueue::front==-1)); //wait until buffer is empty
is really bad because it cause busy waiting which is bad for general performance or battery duration.

Given that it seems that you know nothing about threading, it would be a good idea for you to read some tutorial on this... otherwise your program won't works correctly.

MSDN documentation have a lot of information about that. The following page give you an overview of available functions at the Win32 API level: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686360(v=vs.85).aspx[^]

You can use a semaphore for you problem (circular buffer) or some lock and a bit more logic.

In any case, you want to use a wait function (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx[^]) as an example so that the CPU will be free for use by other programs until some data is ready.

Also in your cqueue class, none of the member should be static as otherwise you cannot use that class more than once. And there are many other problem with your code. It might be a good idea to read some books to help you make more robust programs.
 
Share this answer
 
v2
See @Joseph-M-Newcomer article:Using Semaphores: Multithreaded Producer/Consumer[^].
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900