question about Monitor in c++.net

W

www.brook

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();
}
 
A

Arnaud Debaene

//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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top