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 (i.e. their values will be seemingly random) you invoke undefined behavior.
Related
I am trying to implement a circular queue.
I have declared size of the queue in the header file and I initiated my queue using size variable via constructor.
Here are queue.h and queue.cpp files.
class Queue
{
public:
int size;
int front, rear;
int A[];
Queue(int size);
bool isEmpty();
void enqueue(int n);
int dequeue();
int Peek();
void Display();
int sizeQ();
};
Here is queue.cpp
Queue::Queue(int size)
{
int A[size];
front = rear = -1;
}
bool Queue::isEmpty(){
if((front == -1) && (rear == -1))
return true;
else
return false;
}
void Queue::Display(){
if(isEmpty()){
cout << "Its empty! Nothing to display"<<endl;
}else{
for(int i=0; i<sizeQ(); i++){
cout << A[i] << endl;
}
}
cout <<endl;
}
Here is my main
int main()
{
Queue q1(10);
q1.enqueue(20);
q1.Display();
return 0;
}
The problem: Loop inside display function does not see the size variable although I created object using size inside main. When I debug the program, I saw that size is 0, thus for loop never starts.
What I tried
int Queue::sizeQ(){
return size;
}
I tried to return size via method; however, no luck. What should I do in order to access size variable?
Currently your constructor creates a local array that gets destroyed after it completes. You don't want to do this.
If you want to set the size of an array at run time it has to be declared on the heap. To do that you should change the declaration of the array A like this in the header:
int *A;
Then in your constructor you can allocate the array on the heap:
Queue::Queue(int iSize):
size(iSize), front(-1), rear(-1)
{
A = new int[size];
}
Note the initialiser list is initialising member variables size, front and rear.
You must also deallocate your array. To do this add a destructor to your class Queue and do this:
Queue::~Queue()
{
delete [] A;
}
This will free up the memory used by A.
Queue::Queue(int size)
{
int A[size];
front = rear = -1;
}
You never initialize this->size here. Hence sizeQ() returns uninitialized value of size member.
Add this->size = size; inside the constructor.
EDIT: the int A[size] does not do what you think it does. It is creating a local array and has nothing to do with the member A. Refer to #jignatius answer to see how to fix it.
Initiate size inside constructor like below:
Queue::Queue(int nSize) //changed name of parameter to nSize to remove confusion
{
int A[size];
front = rear = -1;
size = nSize; // Initialize passed param to member variable of class
}
So this is my implementation of a Logical Ring Buffer with Semaphore Synchronization - it is an assignment and most everything here is as described in the book, concerning the implementation of the buffer and semaphores.
Funny thing is this will throw some odd errors most notably Microsoft C++ exception: std::system_error at memory location 0x... for which I can't really find anything online as to what the cause of this is. I assume it might be the accessing of a global variable, but 9/10 times the program will run successfully (assuming I tell VS to continue), the times it does not it is only the last comparison of integers at index 99 of the 2 int arrays.
This is the main method and producer / consumer functions. There is some global variable declaration and initialization, then the Pro/Con threads are created, started, and waited on, finally the results are compared.
#include <iostream> // cout, cin, ignore
#include <thread> // thread, join
#include <random> // rand
/* the number of 'messages' to pass between processes */
const size_t NUMBER_OF_MESSAGES = 100;
/* integer arrays for checking messages after passing */
int PRODUCED_MESSAGES[NUMBER_OF_MESSAGES];
int CONSUMED_MESSAGES[NUMBER_OF_MESSAGES];
/* the logical ring buffer for thread message passing */
LogicalRingBuffer BUFF; // not initiaslized yet ...
void producer_process() {
for (size_t i = 0; i < NUMBER_OF_MESSAGES; i++) {
PRODUCED_MESSAGES[i] = rand();
BUFF.insert(PRODUCED_MESSAGES[i]);
}
}
void consumer_process() {
for (size_t i = 0; i < NUMBER_OF_MESSAGES; i++) {
CONSUMED_MESSAGES[i] = BUFF.remove();
}
}
int main(int agrc, char* argv[]) {
BUFF = LogicalRingBuffer(); /* initializes the buffer */
/* creating the producer and consumer process threads */
std::thread t1(producer_process), t2(consumer_process);
/* wait for both threads to complete before comparisons */
t1.join();
t2.join();
/* iterating through the contents of both integer arrays */
for (size_t i = 0; i < NUMBER_OF_MESSAGES; i++) {
/* printing the contents of the arrays to terminal */
std::cout << "[" << i << "] " << PRODUCED_MESSAGES[i]
<< " <-> " << CONSUMED_MESSAGES[i] << std::endl;
/* inform user and exit program if comparison fails */
if (PRODUCED_MESSAGES[i] != CONSUMED_MESSAGES[i]) {
std::cout << "SYNCHRONIZATION FAILURE!" << std::endl;
std::cin.ignore(); return -1;
}
}
/* inform user of succesful message passing results */
std::cout << "ACTION COMPLETED SUCCESFULLY" << std::endl;
std::cin.ignore(); return 0;
}
And this is the Buffer/Semaphore implementation. I tried to follow the book to a T, and given that almost every time this runs it is successful (other than throwing errors during runtime) I think the synchronicity is stable in this.
struct LogicalRingBuffer{
private:
/* the standard size of the ring buffer */
const static size_t SIZEOF_RING_BUFFER = 10;
/* buffer array and pointers for iteration */
int BUFFER[SIZEOF_RING_BUFFER], *head, *tail;
/* inserts data into the buffer, and recycles the tail pointer */
void push(int data) {
/* insert data into the buffer, increment tail pointer */
*tail = data;
++tail;
/* if tail pointing at end of BUFFER, reset to the front */
if (tail == BUFFER + (SIZEOF_RING_BUFFER - 1)) tail = BUFFER;
}
/* removes data from the buffer, and recycles the head pointer */
int pull() {
/* remove data from the buffer, increment head pointer */
int R = *head;
++head;
/* if head pointing at end of BUFFER, reset to the front */
if (head == BUFFER + (SIZEOF_RING_BUFFER - 1)) head = BUFFER;
/* return the integer data value */
return R;
}
struct Semaphore {
/* the counting value, number of resources */
int count{ NULL };
/* examines resources, holds until ready */
void wait() {
while (count <= 0); //busy wait
--count;
}
/* releases aquired resource (increment) */
void signal() {
++count;
}
} empty, full, mutex; /* Semaphores for Synchronization */
public:
/* initializer for LogicalRingBuffer struct */
LogicalRingBuffer() {
head = tail = BUFFER; // all pointers at BUFFER[0]
empty.count = SIZEOF_RING_BUFFER; // number of open positions
mutex.count = 1; // a binary semaphore, mutex
full.count = 0; // number of used positions
}
/* semaphore synchronized insertion of data */
void insert(int data) {
empty.wait(); // decrements available positions in buff
mutex.wait(); // waits to gain mutual exlusion lock
push(data); // pushes the data into the ring buff
mutex.signal(); // releases the mutual exclusion lock
full.signal(); // increments count of buffered datums
}
/* semaphore synchronized removal of data */
int remove() {
int data{ NULL }; // initialize return data
full.wait(); // decrements count of buffered items
mutex.wait(); // waits to gain mutual exlusion lock
data = pull(); // pulls the data from the ring buff
mutex.signal(); // releases the mutual exlusion lock
empty.signal(); // increments avilable positions in buff
return data; // return integer data
}
};
I guess I just want this to run without any hiccups, so am I missing something here? Because I'm fairly certain the logic is correct and this is something that maybe Visual Studio does, or who knows...
The two threads you create both attempt to lock the mutex by calling Semaphore::wait(). However, there is nothing preventing the threads from reading and writing to the mutex's count variable at the same time. This results in undefined behavior which can cause the system errors you are seeing. You are on the right track in your implementation, but at some point the program has to go to the OS for actual thread-safety. You need to use either the standard library's thread-safety mechanisms to protect concurrent access to this variable or your OS's low-level mechanisms, like Windows's critical sections.
C++11's standard library implements std::mutex which can be used to protect concurrent access to variables which are shared between threads. However, it's implementation is likely as high-level as the one you are trying to implement yourself, so it would make more sense to discard your own implementation in favor of the standard library's.
This was my solution to the problem, compiling in Cygwin GCC with: g++ *.cpp -std=c++11 -w and rewriting the Semaphore::wait() method as follows:
void wait() {
/* the next line was added to avoid count being accessed simultaneously, vvv */
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10)); // <---
while (count <= 0); /* BUSY WAIT */
--count;
}
I plan on running more tests, but so far I have had exactly 0 conflicts when using the thread sleep.
The memory leak caused by the line indicated. "pendingSendReqs.push_back(&f);" in the sendreq() method. I am new to c++ so I can't seem to figure out why the memory leak is occuring. The size of memory leaked is 16 bytes.
class Station {
struct Frame {
enum { Token, Data, Ack } type; // type of frame
unsigned int src; // source id
unsigned int dst; // destination id
unsigned int prio; // priority
} frame;
unsigned int stnId;
static unsigned int requests; // total send requests (if needed)
void data( Frame frame ); // pass frame
void main(); // coroutine main
Station *nextStation;
vector<Frame*> pendingSendReqs;
public:
Station( unsigned int id ) : stnId(id) { }
~Station() {
for (int i = 0; i < pendingSendReqs.size(); i++) {
delete pendingSendReqs.at(i);
cout << "~: " << pendingSendReqs.at(i) << endl;
}
}
//unsigned int getId() { return stnId; }
void setup( Station *nexthop ) { // supply next hop
//*nexthop is the object
nextStation = nexthop;
//cout << "size: " << sizeof(*nexthop) << endl;
}
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) { // store send request
Frame f;
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
}
void start(); // inject token and start
};
This is not a memory leak
pendingSendReqs.push_back(&f);
it is future undefined behaviour. You are storing the address of a local variable. Any attempt to de-reference one of those pointers outside of the scope of the function is undefined behaviour.
You have to ask yourself whether you really need a vector of pointers. If you don't know the answer to that, it is likely that you don't.
You're storing pointers to local variables, which will automatically get destroyed, inside the vector. This is illegal.
vector<Frame*> pendingSendReqs;
// this is a vector of pointers to struct and not a vector of structs
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) {
Frame f; // this automatic variable will get destroyed when sendreq returns
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
// because you're going to hold on to this address which will mean
// nothing when this function returns
}
The way you intend to do it is:
vector<Frame> pendingSendReqs;
and inside sendreq:
pendingSendReqs.push_back(f); // store the object's copy instead of it's address so that it outlives the life of this local
when
void sendreq( unsigned int round, unsigned int dst, unsigned int prio )
ends,
your vector pendingSendReqs will contain pointers to variables that have been eliminated ( because are local variable ), and will contain garbage, and will give you a crash.
I am modeling a sink-type device that data can be written to. This will be used in the context of writing to 512 byte blocks.
Internal to the sink, bytes are buffered to a 512 byte vector; when full, this buffer is written to a currently selected 512 byte block. The buffer is then emptied and the next block can be written to.
My problem is thus: if the buffer is not at the point of being full, e.g. when there is no more incoming data, how can the remaining contents be successfully flushed? I could of course implement a public flush function but this doesn't feel particularly elegant. Idea:
class DataWriter
{
public:
DataWriter(/* ommitted for brevity */) {}
typedef char char_type;
typedef boost::iostreams::seekable_device_tag category;
std::streamsize write(char_type const * const buf, std::streamsize const n) const
{
for(int i = 0; i < n; ++i) {
bufferByteForWriting(s[i]);
}
return n;
}
// to flush any remaining data. Doesn't feel
// that elegant
void flush()
{
writeBufferedDataToBlock(m_buffer.size());
}
private:
void bufferByteForWriting(char const byte) const
{
if(m_buffer.size() == 512) {
writeBufferedDataToBlock(512);
std::vector<uint8_t>.swap(m_buffer);
}
}
writeBufferedDataToBlock(unsigned long const count) const
{
// omitted for brevity
// this writes data to a specific block
// and increments to a new 512 byte block
// that the next 512 byte chunk of data will be written to
}
std::vector<uint8_t> m_buffer;
};
I face a strange error with pthreads in C++, I try to run this code:
typedef struct
{
struct sockaddr_in clienAddr;
int clientLength;
string message;
}param;
pthread_t clientThread;
param sentParam ;
sentParam.clienAddr = clientAddress;
sentParam.clientLength= client_info;
sentParam.message=buffString;
cout <<"sentParam: "<<sentParam.message<<endl;
// it prints well.
int i = pthread_create(&clientThread, NULL, handleClientRequestRead,&sentParam );
cout <<"i: "<<i<<endl;
the function which be called
void* handleClientRequestRead(void* params)
{
// cout<<"params: "<< ;
string msg = (( param *)(params))->message;
}
When I try to print msg it's empty. Any help will be appreciated
My guess is that when handleClientRequestRead gets called sentParam has already gone out of scope and its memory has been reused for other purposes.
You should allocate memory for your parameters in a location that will still be valid when you'll access it from the thread (e.g. on the heap, keeping in mind that you must free it when you don't need it anymore; a valid help can be shared_ptr).
By the way, in C++ you don't need the typedef trick for structs.
I agree with #Matteo above:
struct param
{
struct sockaddr_in clienAddr;
int clientLength;
string message;
};
void someFunction()
{
static int sentCount = 0;
static param sentParam[10];
// ^^^^^^ Notice these are static
// Thus they will last the length of the program.
// An alternative is to dynamically creation but then you have
// to destroy them at some point.
//
if (count >= 10)
{ throw std::runtime_error("Too many threads");
}
// If you want to keep more than 10 or use a dynamic number
// then use a std::list, NOT a std::vector
sentParam[sentCount].clienAddr = clientAddress;
sentParam[sentCount].clientLength= client_info;
sentParam[sentCount].message=buffString;
cout <<"sentParam: "<<sentParam.message<<endl;
// it prints well.
pthread_t clientThread;
int i = pthread_create(&clientThread, NULL, handleClientRequestRead,&sentParam[sentCount] );
cout <<"i: "<<i<<endl;
if (i == 0)
{
++sentCount;
}
}