By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,364 Members | 1,254 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,364 IT Pros & Developers. It's quick & easy.

question about Monitor in c++.net

P: n/a

I have a VC++.net code. Two threads are created, one thread keeps
appending elements to the queue, another keeps deleting an element from
the queue.
I tried to use monitor, but it seems that the there is problem. in the
thread of the deleting, seems that the deleting function entered twice
and both
try to delete the queue. The first thread find it is not empty, and try
to delete an element, but before this thread actually delete it,
another thread already
delete the last element. It results in an exception. My code is
attached below.

Can anyone tell me what is wrong with my code?
Thanks in advance

// This is the main project file for VC++ application project
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;
using namespace System::Collections;
using namespace System::Threading;

// Class definition
public __gc class MonitorSample {
public:

MonitorSample();
void AddElement(Object* qValue);
void DeleteElement();
void PrintAllElements();

static void AppendFunction();
static void DeleteFunction();
static void exp();

static MonitorSample *m_sample;

private:

Queue* m_inputQueue;
};

//Define the queue to safe thread access.
MonitorSample::MonitorSample()
{
m_inputQueue = new Queue();
}
//Add an element to the queue and obtain the monitor lock for the queue
object.
void MonitorSample::AddElement(Object* qValue)
{
//Lock the queue.
if(!Monitor::TryEnter(m_inputQueue,100)) return ;
if(m_inputQueue->Count==10)
{
Console::WriteLine("buffer full\n");
}
else m_inputQueue->Enqueue(qValue);
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}
//Delete all elements that equal the given object and obtain the
monitor lock for the queue object.
void MonitorSample::DeleteElement()
{
//Lock the queue.
if(!Monitor::TryEnter(m_inputQueue,100)) return ;
int counter = m_inputQueue->Count;
while(counter > 0)
{
Object* elm = m_inputQueue->Dequeue();
}
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}

//Print all queue elements.
void MonitorSample::PrintAllElements()
{
//Lock the queue.
if(!Monitor::TryEnter(m_inputQueue,100)) return ;

Console::WriteLine("all elements I have:\n");

IEnumerator* elmEnum = m_inputQueue->GetEnumerator();
while(elmEnum->MoveNext())
{
//Print the next element.
Console::WriteLine(elmEnum->Current->ToString());
}
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}
void MonitorSample::AppendFunction()
{
Random *a = new Random();
for(;;)
{
Console::WriteLine("let me append");
// Monitor::Enter(m_sample);
m_sample->AddElement((__box(a->Next(100))));
m_sample->PrintAllElements();

// Monitor::Exit(m_sample);
//Thread::Sleep(a->Next(100,1000));
}
}
void MonitorSample::DeleteFunction()
{
Random *a = new Random();
for(;;)
{
Console::WriteLine("let me delete");

// Monitor::Enter(m_sample);

m_sample->DeleteElement();
m_sample->PrintAllElements();

// Monitor::Exit(m_sample);
//Thread::Sleep(a->Next(100,1000));
}
}

void MonitorSample::exp()
{

Thread * appenthread = new Thread(new
ThreadStart(NULL,AppendFunction));
appenthread->Start();

Thread * deletethread = new Thread(new
ThreadStart(NULL,DeleteFunction));
deletethread->Start();

Thread::Sleep(100000);

deletethread->Abort();
appenthread->Abort();

}

//start multiple thread to do the
void main() {

MonitorSample::m_sample = new MonitorSample();

MonitorSample::exp();
}

Feb 19 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
ww*******@gmail.com wrote:

//Delete all elements that equal the given object and obtain the
monitor lock for the queue object.
void MonitorSample::DeleteElement()
{
//Lock the queue.
if(!Monitor::TryEnter(m_inputQueue,100)) return ;
int counter = m_inputQueue->Count;
while(counter > 0)
{
Object* elm = m_inputQueue->Dequeue();
}
//Unlock the queue.
Monitor::Exit(m_inputQueue);
} How do you expect to get out of the while loop here?

Another point : All your calls to Monitor::Exit should be in finally blocks,
in order to be sure the lock is released even in case of exception.

Arnaud
MVP - VC


//Print all queue elements.
void MonitorSample::PrintAllElements()
{
//Lock the queue.
if(!Monitor::TryEnter(m_inputQueue,100)) return ;

Console::WriteLine("all elements I have:\n");

IEnumerator* elmEnum = m_inputQueue->GetEnumerator();
while(elmEnum->MoveNext())
{
//Print the next element.
Console::WriteLine(elmEnum->Current->ToString());
}
//Unlock the queue.
Monitor::Exit(m_inputQueue);
}
void MonitorSample::AppendFunction()
{
Random *a = new Random();
for(;;)
{
Console::WriteLine("let me append");
// Monitor::Enter(m_sample);
m_sample->AddElement((__box(a->Next(100))));
m_sample->PrintAllElements();

// Monitor::Exit(m_sample);
//Thread::Sleep(a->Next(100,1000));
}
}
void MonitorSample::DeleteFunction()
{
Random *a = new Random();
for(;;)
{
Console::WriteLine("let me delete");

// Monitor::Enter(m_sample);

m_sample->DeleteElement();
m_sample->PrintAllElements();

// Monitor::Exit(m_sample);
//Thread::Sleep(a->Next(100,1000));
}
}

void MonitorSample::exp()
{

Thread * appenthread = new Thread(new
ThreadStart(NULL,AppendFunction));
appenthread->Start();

Thread * deletethread = new Thread(new
ThreadStart(NULL,DeleteFunction));
deletethread->Start();

Thread::Sleep(100000);

deletethread->Abort();
appenthread->Abort();

}

//start multiple thread to do the
void main() {

MonitorSample::m_sample = new MonitorSample();

MonitorSample::exp();
}

Feb 19 '06 #2

P: n/a
You are right, the while should be if!

Thanks for point it out.

Feb 19 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.