• Some users have recently had their accounts hijacked. It seems that the now defunct EVGA forums might have compromised your password there and seems many are using the same PW here. We would suggest you UPDATE YOUR PASSWORD and TURN ON 2FA for your account here to further secure it. None of the compromised accounts had 2FA turned on.
    Once you have enabled 2FA, your account will be updated soon to show a badge, letting other members know that you use 2FA to protect your account. This should be beneficial for everyone that uses FSFT.

C# - Multithreading Questions

Alexsktbrdng

Limp Gawd
Joined
Dec 31, 2002
Messages
206
I am trying to create a program that has two threads (producer and consumer) manipulating the same object (an integer). There will be two loops running, the first has the producer write a number (it goes 1,2,3,4) and the consumer then reads it and totals it. The second loop I need to do must have the producer write A,B,C,D and then have the consumer read it, and I'm having trouble creating a loops similar to this

for ( int count = 1; count <= 4; count++ )



But instead of 1,2,3,4 have it use A,B,C,D. Does anyone have an idea of how to accomplish that? This is what I have so far, the code is a bit jumbled but please bare with me. Thanks!




Code:
// In-Exercise 2: Synchronized2.cs

 

// (1) Extend the Synchronized example by adding a SharedString class.

// (2) Pass a SharedString object to Consumer and Producer constructor method calls.

// (3) Consumer object writes "A", "B", "C" and "D" into a SharedMsg object.

// (4) Producer object reads "A", "B", "C" and "D" in order from the SharedMsg object.

using System;

using System.Threading;

//

namespace Synchronized2

{

// this class synchronizes access to an integer

public class SharedAndSynchronized

{

// buffer shared by producer and consumer threads 

private int buffer = -1;

// bufferFull checks if buffer is full

private bool bufferFull = false; 

public void SetBuffer(int v)

{

// Producer try acquiring lock for this object

Monitor.Enter( this );

// if buffer is full (the previous value has not be read), 

// ask this Producer thread to wait on this shared object

if ( bufferFull == true )

{

Console.WriteLine( Thread.CurrentThread.Name + " tries to write again." );

DisplayState( "Buffer full, " + Thread.CurrentThread.Name + " waits....." );

Monitor.Wait( this );

}

// if buffer is empty, write a new value v

buffer = v;

// set bufferFull to true to indicate a new value is available

bufferFull = true;

DisplayState( Thread.CurrentThread.Name + " writes " + buffer );

// tell waiting Consumer thread (if there is one) to become ready to execute

Monitor.Pulse( this );

// release lock on this object

Monitor.Exit( this );

} // end SetBuffer

public int GetBuffer()

{ 

// Consumer try obtaining lock on this object

Monitor.Enter( this );

// if no data to read, ask this Consumer thread to wait on this shared object

if ( bufferFull == false )

{

Console.WriteLine( Thread.CurrentThread.Name + " tries to read." );

DisplayState( "Buffer empty, " + Thread.CurrentThread.Name + " waits....." );

Monitor.Wait( this );

}

// if there is data to read, set bufferFull to false before reading

bufferFull = false; 


DisplayState( "*" + Thread.CurrentThread.Name + " reads " + buffer + "*");

// tell waiting Producer thread (if there is one) to become ready to execute

Monitor.Pulse( this );

// release lock on this object

Monitor.Exit( this );

// finally actually read the buffer data

return buffer;

} // end GetBuffer

 

// display current operation and buffer state

public void DisplayState( string operation )

{

Console.WriteLine( "{0,-35}{1,-9}{2}\n", operation, buffer, bufferFull );

}

} // end class SharedAndSynchronized


//-----------------------------------------------------

// this SharedString class synchronizes access to a string

public class SharedString// write the set and get methods, you can copy and paste the get and set buffer methods. 

//complete this part below, the shared string part. you can copy and past and modify

//4 lines of code on get and set. modify producer method to get the shared string object. 

//in producer method, call the switch the reading and writing between producer and consumer.

{

// msg shared by producer and consumer threads??

// msgFull checks if msg is full??

public void SetMsg(string s) //??

{

// Producer try acquiring lock for this object

Monitor.Enter(this);

// if buffer is full (the previous value has not be read), 

// ask this Producer thread to wait on this shared object

if (bufferFull == true)

{

Console.WriteLine(Thread.CurrentThread.Name + " tries to write again.");

DisplayState("Buffer full, " + Thread.CurrentThread.Name + " waits.....");

Monitor.Wait(this);

}

// if buffer is empty, write a new value v

buffer = v;

// set bufferFull to true to indicate a new value is available

bufferFull = true;

DisplayState(Thread.CurrentThread.Name + " writes " + buffer);

// tell waiting Consumer thread (if there is one) to become ready to execute

Monitor.Pulse(this);

// release lock on this object

Monitor.Exit(this);


} // end SetMsg

public string GetMsg() //??

{

// Consumer try obtaining lock on this object

Monitor.Enter(this);

// if no data to read, ask this Consumer thread to wait on this shared object

if (bufferFull == false)

{

Console.WriteLine(Thread.CurrentThread.Name + " tries to read.");

DisplayState("Buffer empty, " + Thread.CurrentThread.Name + " waits.....");

Monitor.Wait(this);

}

// if there is data to read, set bufferFull to false before reading

bufferFull = false;

DisplayState("*" + Thread.CurrentThread.Name + " reads " + buffer + "*");

// tell waiting Producer thread (if there is one) to become ready to execute

Monitor.Pulse(this);

// release lock on this object

Monitor.Exit(this);

// finally actually read the buffer data

return buffer;

 


} // end GetMsg

 

// display current operation and buffer state

public void DisplayState( string operation )

{

Console.WriteLine( "{0,-35}{1,-9}{2}\n", operation, msg, msgFull );

}

} // end class SharedString

 

 

// class Producer's Produce method controls a thread that

// stores values from 1 to 4 in sharedLocation and reads A to D from sharedMsg

class Producer 

{

private SharedAndSynchronized sharedLocation;

private Random randomSleepTime;

// ??

public Producer( SharedAndSynchronized shared, Random random )

{

sharedLocation = shared;

randomSleepTime = random;

// ?? add an object from the shared msg class

}

// store values 1-4 in object sharedLocation and read A-D from object sharedMsg

public void Produce()

{

string message;


// sleep for random interval upto 3000 milliseconds,

for (string message //THIS IS WHERE I STOPPED!!!!

Thread.Sleep( randomSleepTime.Next(1, 3000);

// set sharedLocation's buffer value,

// and reads sharedMsg's msg string

for ( int count = 1; count <= 4; count++ ) 

{

Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );

sharedLocation.SetBuffer( count ); 

// reads from sharedmsg

}

Console.WriteLine( Thread.CurrentThread.Name + " done producing.\n" );

} // end method Produce

} // end class Producer

// class Consumer's Consume method controls a thread that

// loops four times, reads a value from sharedLocation, and writes A-D to sharedMsg

class Consumer

{

private SharedAndSynchronized sharedLocation;

private Random randomSleepTime;

// ??

public Consumer( SharedAndSynchronized shared, Random random, SharedString ss )

{

sharedLocation = shared;

randomSleepTime = random;

// ??

}

// read sharedLocation's value four times and write A-D to sharedMsg

public void Consume()

{

int sum = 0;

// A String array with "A", "B", "C" and "D"??

// get current thread

Thread current = Thread.CurrentThread;

// sleep for random interval upto 3000 milliseconds,

// add sharedLocation's buffer value to sum

// and writes A-D to sharedMsg

for ( int count = 1; count <= 4; count++ )

{

Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );

sum += sharedLocation.GetBuffer();

// ??

}


Console.WriteLine( "*" + Thread.CurrentThread.Name + 

" read values totaling: " + sum + "* (should be 10).\n" );

} // end method Consume

} // end class Consumer

// this class creates producer and consumer threads

class SharedCell

{

// create producer and consumer threads and start them

static void Main( string[] args )

{

// create shared object used by threads

SharedAndSynchronized holdInteger = new SharedAndSynchronized();

// Random object used by each thread

Random random = new Random();

// create SharedString object??


// create Producer and Consumer objects

Producer producer = new Producer( holdInteger, random ); //??

Consumer consumer = new Consumer( holdInteger, random ); //??

// output column heads and initial buffer state

Console.WriteLine( "{0,-35}{1,-9}{2}", "Operation", "Buffer", "Value to Read?" );

Console.WriteLine( "-----------------------------------------------------------" );

holdInteger.DisplayState( "Initial state" );

// create threads for producer and consumer and set 

// delegates for each thread

ThreadStart pts = new ThreadStart( producer.Produce ); 

Thread producerThread = new Thread( pts );

producerThread.Name = "Producer";

ThreadStart cts = new ThreadStart( consumer.Consume );

Thread consumerThread = new Thread( cts );

consumerThread.Name = "Consumer";

// start each thread

producerThread.Start();

consumerThread.Start();

} // end method Main

} // end class SharedCell

}
 
It would be a lot easy to pull through your code if you used
Code:
 tags.

Without trying to slug through the poor formatting in your code, your fundamental question is easy; loop through the characters if you want instead of the integers:

[CODE]
for (char c = 'A'; c <= 'D'; c++ )
 
I appreciate the help that is my biggest problem with the assigment. I fixed that up and will clean my code up more and get back to you with any more questions (which I'm sure I will have). Thanks for the help!
 
Okay,
I have updated the code alot, this is what I have now:

Code:
// Description:
//	(1) Extend the Synchronized example by adding a SharedString class.
//	(2) Pass a SharedString object to Consumer and Producer constructor method calls.
//	(3) Consumer object writes "A", "B", "C" and "D" into a SharedMsg object.
//  (4) Producer object reads "A", "B", "C" and "D" in order from the SharedMsg object.

using System;
using System.Threading;
//
namespace Synchronized2
{
   // this class synchronizes access to an integer
   public class SharedAndSynchronized
   {
      // buffer shared by producer and consumer threads 
      private int buffer = -1;

      // bufferFull checks if buffer is full
      private bool bufferFull = false;  

	   public void SetBuffer(int v)
      {
            // Producer try acquiring lock for this object
            Monitor.Enter( this );

		    // if buffer is full (the previous value has not be read), 
		    // ask this Producer thread to wait on this shared object
            if ( bufferFull == true )
            {
               Console.WriteLine( Thread.CurrentThread.Name + " tries to write again." );

               DisplayState( "Buffer full, " + Thread.CurrentThread.Name + " waits....." );

               Monitor.Wait( this );
            }

            // if buffer is empty, write a new value v
            buffer = v;

		    // set bufferFull to true to indicate a new value is available
            bufferFull = true;

            DisplayState( Thread.CurrentThread.Name + " writes " + buffer );

            // tell waiting Consumer thread (if there is one) to become ready to execute
            Monitor.Pulse( this );

            // release lock on this object
            Monitor.Exit( this );

      } // end SetBuffer

	  public int GetBuffer()
	  {      
		   // Consumer try obtaining lock on this object
		   Monitor.Enter( this );

		   // if no data to read, ask this Consumer thread to wait on this shared object
		   if ( bufferFull == false )
		   {
			   Console.WriteLine( Thread.CurrentThread.Name + " tries to read." );

			   DisplayState( "Buffer empty, " + Thread.CurrentThread.Name + " waits....." );

			   Monitor.Wait( this );
		   }

		   // if there is data to read, set bufferFull to false before reading
		   bufferFull = false;    
                                 
		   DisplayState( "*" + Thread.CurrentThread.Name + " reads " + buffer + "*");

		   // tell waiting Producer thread (if there is one) to become ready to execute
		   Monitor.Pulse( this );

		   // release lock on this object
		   Monitor.Exit( this );

		   // finally actually read the buffer data
		   return buffer;

	  } // end GetBuffer


      // display current operation and buffer state
      public void DisplayState( string operation )
      {
         Console.WriteLine( "{0,-35}{1,-9}{2}\n", operation, buffer, bufferFull );
      }

   } // end class SharedAndSynchronized

    
   //-----------------------------------------------------
	// this SharedString class synchronizes access to a string
	public class SharedString// write the set and get methods, you can copy and paste the get and set buffer methods.  
        //complete this part below, the shared string part.  you can copy and past and modify
        //4 lines of code on get and set.  modify producer method to get the shared string object.  
        //in producer method, call the switch the reading and writing between producer and consumer.
	{
		// msg shared by producer and consumer threads?? DONE
        private string msg;
		// msgFull checks if msg is full?? DONE
        private bool msgFull = false;  

		public void SetMsg(string s) // CHANGED THIS TO HAVE MSG
		{
            // Producer try acquiring lock for this object
            Monitor.Enter(this);

            // if msg is full (the previous value has not be read), 
            // ask this Producer thread to wait on this shared object
            if (msgFull == true)
            {
                Console.WriteLine(Thread.CurrentThread.Name + " tries to write again.");

                DisplayState("Msg full, " + Thread.CurrentThread.Name + " waits.....");

                Monitor.Wait(this);
            }

            // if msg is empty, write a new value s
            msg = s;

            // set msgFull to true to indicate a new value is available
            msgFull = true;

            DisplayState(Thread.CurrentThread.Name + " writes " + msg);

            // tell waiting Consumer thread (if there is one) to become ready to execute
            Monitor.Pulse(this);

            // release lock on this object
            Monitor.Exit(this);

		
		} // end SetMsg

		public string GetMsg() //CHANGED THIS TO HAVE MSG
		{
            // Consumer try obtaining lock on this object
            Monitor.Enter(this);

            // if no data to read, ask this Consumer thread to wait on this shared object
            if (msgFull == false)
            {
                Console.WriteLine(Thread.CurrentThread.Name + " tries to read.");

                DisplayState("Msg empty, " + Thread.CurrentThread.Name + " waits.....");

                Monitor.Wait(this);
            }

            // if there is data to read, set msgFull to false before reading
            msgFull = false;

            DisplayState("*" + Thread.CurrentThread.Name + " reads " + msg + "*");

            // tell waiting Producer thread (if there is one) to become ready to execute
            Monitor.Pulse(this);

            // release lock on this object
            Monitor.Exit(this);

            // finally actually read the msg data
            Convert.ToString(msg);
            return  msg;


			
		} // end GetMsg


		// display current operation and MSG state
		public void DisplayState( string operation )
		{
			Console.WriteLine( "{0,-35}{1,-9}{2}\n", operation, msg, msgFull );
		}

	} // end class SharedString // MAY BE DONE WITH THIS CLASS!



   // class Producer's Produce method controls a thread that
   // stores values from 1 to 4 in sharedLocation and reads A to D from sharedMsg. Switch it up for the ABCD
   class Producer 
   {
      private SharedAndSynchronized sharedLocation;
      private Random randomSleepTime;
       private SharedString sharedLocationString;
       //DONE??

      public Producer( SharedAndSynchronized shared,SharedString sharedstg, Random random )
      {
         sharedLocation = shared;
         randomSleepTime = random;
         sharedLocationString = sharedstg;  
		 // ?? add an object from the shared msg class DONE
      }

      // store values 1-4 in object sharedLocation and read A-D from object sharedMsg
      public void Produce()
      {
		//NOT SURE IF I NEED THIS string message;
        
         // sleep for random interval upto 3000 milliseconds,
         // for (string message
          //Thread.Sleep( randomSleepTime.Next(1, 3000);

         // set sharedLocation's buffer value,
		 // and reads sharedMsg's msg string
         for ( int count = 1; count <= 4; count++ ) 
         {
            Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
            sharedLocation.SetBuffer( count ); 
			// reads from sharedmsg, it does this in the following lines
            
         }
          //Producer reading A, B, C, D from char C in consumes method
          for ( char j ='A'; j<='D'; j++)
          {
            Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
			sharedLocationString.GetMsg();
         }

         Console.WriteLine( Thread.CurrentThread.Name + " done producing.\n" );

      } // end method Produce

   } // end class Producer

   // class Consumer's Consume method controls a thread that
   // loops four times, reads a value from sharedLocation, and writes A-D to sharedMsg
   class Consumer
   {
      private SharedAndSynchronized sharedLocation;
      private Random randomSleepTime;
       private SharedString sharedLocationString;

      public Consumer( SharedAndSynchronized shared, Random random, SharedString ss )
      {
         sharedLocation = shared;
         randomSleepTime = random;
         sharedLocationString = ss;
      }

      // read sharedLocation's value four times and write A-D to sharedMsg
      public void Consume()
      {
         char c;
		
        

         // get current thread
         Thread current = Thread.CurrentThread;

         // sleep for random interval upto 3000 milliseconds,
         // add sharedLocation's buffer value to sum
		 // and writes A-D to sharedMsg
         for ( int count = 1; count <= 4; count++ )
         {
            Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
            sum += sharedLocation.GetBuffer();
			
         }
         // A String array with "A", "B", "C" and "D"
              for ( char j ='A'; j<='D'; j++)
          {
            Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
			sharedLocationString.SetMsg();
         }
      
         Console.WriteLine( "*" + Thread.CurrentThread.Name + 
            " read values totaling: " + sum + "* (should be 10).\n" );

      } // end method Consume

   } // end class Consumer

   // this class creates producer and consumer threads
   class SharedCell
   {
      // create producer and consumer threads and start them
       //I THINK MAIN IS ALL DONE
      static void Main( string[] args )
      {
         // create shared object used by threads
         SharedAndSynchronized holdInteger = new SharedAndSynchronized();

         // Random object used by each thread
         Random random = new Random();

	     // create SharedString object??
         SharedString holdChar = new SharedString();

         // create Producer and Consumer objects
         Producer producer = new Producer( holdInteger, holdChar, random ); //Create new holdChar objects
         //Producer producer = new Producer(holdChar, random);

         Consumer consumer = new Consumer( holdInteger, holdChar, random ); //Create new holdChar objects
        // Consumer consumer = new Consumer(holdChar, random);

         // output column heads and initial buffer state
         Console.WriteLine( "{0,-35}{1,-9}{2}", "Operation", "Buffer", "Value to Read?" );
		 Console.WriteLine( "-----------------------------------------------------------" );
         holdInteger.DisplayState( "Initial state"  );
         holdChar.DisplayState("Initial state");

         // create threads for producer and consumer and set 
         // delegates for each thread
        ThreadStart pts = new ThreadStart( producer.Produce ); 
         Thread producerThread = new Thread( pts );
         producerThread.Name = "Producer";

        ThreadStart cts = new ThreadStart( consumer.Consume );
         Thread consumerThread = new Thread( cts );
         consumerThread.Name = "Consumer";

         // start each thread
         producerThread.Start();
         consumerThread.Start();

      } // end method Main

   } // end class SharedCell
}

I'm gettin a few errors basically involving overloading the producer and consumer, and some errors where i'm not sure if I should be using string or char. Here are the errors I currently am receiving.

Code:
The name 'sum' does not exist in the current context
	
No overload for method 'SetMsg' takes '0' arguments	

The name 'sum' does not exist in the current context	

The best overloaded method match for 'Synchronized2.Consumer.Consumer(Synchronized2.SharedAndSynchronized, System.Random, Synchronized2.SharedString)' has some invalid arguments

Argument '2': cannot convert from 'Synchronized2.SharedString' to 'System.Random'

Argument '3': cannot convert from 'System.Random' to 'Synchronized2.SharedString'
 
I think the error messages are pretty self-explanatory. Which ones are you having trouble with?
 
Back
Top