Previous Section  < Day Day Up >  Next Section

Chapter 13

A1:

False. An asynchronous delegate may have a return value.

A2:

ia is an IAsyncResult object returned by BeginInvoke that is later passed to EndInvoke

p1 is a string parameter defined in the delegate's signature.

p2 is an optional callback method.

p3 is a value that can be passed to the callback method when the thread ends.

A3:

Thread Local Storage (TLS) holds state information about a thread. This is required when a thread is swapped out before completion.

A4:

The default number of threads in a thread pool is 25.

A5:

ThreadStart and ParameterizedThreadStart delegates are used to create a thread. The latter permits parameters to be passed to a thread.

A6:

lock (this) { } expands into an identical construct.

A7:

a. The message is never printed because the semaphore is created with zero initial threads, and then goes into a wait state.

A8:

b. It prints "Primary Thread" followed by "Worker Thread". The mutex in the main thread is created with ownership. The spawned thread's mutex must wait for the original one to finish before its thread continues processing.

A9:

There are many solutions. Here is one based on not grabbing a chopstick until both are available:


using System;

using System.Threading;

class Stick {

  //Sticks available are designated as true

  bool[] chopStick = {true, true, true, true, true}; 

  // Attempt to pick up left and right chopstick

  public void GetSticks(int left, int right) 

  {

    lock (this) 

    {

      // Release lock and wait until both chopsticks are free

      while (!chopStick[left] && !chopStick[right]) 

         Monitor.Wait(this);

      chopStick[right] = false; chopStick[left] = false;

    }

  }



  // Put chopsticks down

  public void FreeSticks(int left, int right) 

  {

    lock(this) 

    {

      chopStick[right] = true; 

      chopStick[left]  = true;

      // Signal threads in queue that chopsticks are available

      Monitor.PulseAll(this);

    }

  }

}

class Philosopher 

{

  int n;             // Philosopher number 

  int eatDelay;  

  int thinkDelay;

  int left, right;  

  Stick chopSticks;

  public Philosopher (int n, int thinkTime,int eatTime, 

                      Stick sticks) 

  {

    this.n = n;

    this.eatDelay   = eatTime;

    this.thinkDelay = thinkTime;

    this.chopSticks = sticks;

    // Fifth philosopher has chopstick 1 on left

    left = n == 5 ? 1 : n+1;  

    right = n;

    new Thread(new ThreadStart(Run)).Start();

  }

  

  public void Run() 

  {

    while(true)

    {

      try

      {

        // Philosopher thinks for random amount of time

        Thread.Sleep(thinkDelay);

        chopSticks.GetSticks(left-1, right-1);

        Console.WriteLine("Philosopher {0} is eating for 

                        [1} ms ",n, eatDelay);

        Thread.Sleep(eatDelay);

        chopSticks.FreeSticks(left-1, right-1);   

      } catch { return; }

    }

  }

}    // End of class Philosopher



public class Diners 

{

  public static void Main() 

  {

    Stick sticks = new Stick();

    // Create thread for each philosopher

    // Eat time is random

    Random r = new Random(DateTime.Now.Millisecond);

    new Philosopher(1, 100, r.Next(500), sticks);

    new Philosopher(2, 200, r.Next(500), sticks);

    new Philosopher(3, 300, r.Next(500), sticks);

    new Philosopher(4, 400, r.Next(500), sticks);

    new Philosopher(5, 500, r.Next(500), sticks);

  }

}


    Previous Section  < Day Day Up >  Next Section