Archive for the ‘MultiThreading’ Category.

C# MultiThreading Using ThreadPool, Anonymous Delegates and Locks

What is the quickest, least lines of code, way of creating a thread in ones code?

The answer is to create an anonymous delegate and pass it over to the ThreadPool object. Below is a class comically called DirtyPool which demonstrates these items:

  1. Self contained code, call the static ShowExample to run the console example.
  2. Uses three threads, two to generate data and one to write it out.
  3. Calls QueueUserWorkItem off of the ThreadPool to launch the threads.
  4. Demonstrates thread safe access to shared resource by using lock.

Here is the quick code example:

public class DirtyPool
{
    // Data held in this queue.
    public static Queue<string> _Operations
                      = new Queue<string>();

    // Status objects for printer delegate/thred
    // to know when to exit.
    bool OneEnded;
    bool TwoEnded;

    public static void ShowExample()
    {
        DirtyPool dp = new DirtyPool();
        dp.DoIt();
        // Sleep long enough so not to kill the threads.
        Thread.Sleep( 10000 );
    }

    public  void SetData( string who )
    {
        lock ( _Operations )
            _Operations.Enqueue( who );

    }

    public  void PrintData( )
    {
        lock ( _Operations )
            if (_Operations.Count > 0)
                Console.WriteLine( _Operations.Dequeue() );

    }

    public void DoIt()
    {

    ThreadPool.QueueUserWorkItem(
        delegate // Anonomous Delegate For Creation 1
        {

            for ( int index = 0; index < 5; ++index )
            {
                Thread.Sleep( 1500 );
                SetData( "Pool 1: " + index  );
            }
            OneEnded = true;
        }
    );

    ThreadPool.QueueUserWorkItem(
       delegate // Anonomous Delegate For Creation 2
       {
           for ( int index = 0; index < 5; ++index )
           {
               Thread.Sleep( 1000 );
               SetData( "Pool 2: " + index );
           }

           TwoEnded = true;

       }
   );

    ThreadPool.QueueUserWorkItem(
            delegate // Anonomous Delegate For Extraction & Printing
            {
             while ( !( TwoEnded && OneEnded ) )
                 PrintData();

             PrintData(); // Just in case...

            }
        );

    }

}

Here is the output:

Pool 2: 0

Pool 1: 0Pool 2: 1

Pool 1: 1

Pool 2: 2

Pool 2: 3

Pool 1: 2

Pool 2: 4

Pool 1: 3

Pool 1: 4

Press any key to continue . . .

 

Share

C# Thread Safety for Whole Objects Using a Semaphore

The need could arise where one has client threads which need to access individual objects which may not be inherently thread safe. If the object or data has not locked its internal processing, how is one to assure thread safety when two threads have the same object? The short answer is a Semaphore class which is used to limit a particular resource. We will demonstrate the LockEncapsulator class which uses a Semaphore and encapsulates the a target data/class which is the target resource for threads.

Order Example

Say for example you have a list of orders. Each of the order objects were written without threading in mind. You now have an application which does multithreading and could conceivable access the same order object in multiple threads.

Here is a non thread safe class below that will simulate our needs. It simply takes in an order number and prints out that ID with who requested it. Note, I don’t recommend writing to the console, or doing any GUI operation on separate threads; it is only shown here for example purposes.

public class Order
{
    public Order( int orderNumber )
    {
        OrderNumber = orderNumber;
    }

    public int OrderNumber { get; set; }

    public void PrintOrder( string threadID )
    {
        Console.WriteLine( "Order {0} accessed by {1}", OrderNumber, threadID );
    }

}

LockEncapsulator

We will create a class which can encapsulate the order class, or any other and provide a methodology of locking that object, using a semaphore, and releasing it to be used by other threads.

// Holds an object and uses a semephore to guarantee that
   // the object is only accessed one and only one time.
   public class LockEncapsulator<T>
   {
       private readonly T targetObject;
       private Semaphore semLock;

       public LockEncapsulator(T target)
       {
           targetObject = target;

           // 1 object, for only 1 operation.
           semLock = new Semaphore( 1, 1 );

       }

       // Called by the consumer to start.
       public T InstanceGet()
       {
           semLock.WaitOne();
           return targetObject;
       }

       // Called by the consumer when done.
       public void InstanceReturn()
       {
           semLock.Release();
       }

   }

The thread will access the target object by calling InstanceGet. When that is called, if no other thread has it locked, it will immediately return with, in our case, the order instance. Otherwise if it is being used, then the thread will wait until the object is released. When the operations are done, the thread must call InstanceReturn to allow other threads to use it. That due diligence will allow us to lock our resource, Order, and not have to worry about individual locking of code sections.

The following code demonstrates how that locking using the LockEncapsulator can be done. It will create two orders, saving them to a dictionary. Then it will create two threads, Thing1 and Thing2. Each thread will receive order 1001. Thing1 will take its time and wait 5 seconds before returning the object and calling InstanceReturn.

public class OrderManager
{
    // First int is the Order number
    public Dictionary<int, LockEncapsulator<Order>> Storage { get; set; }


    public static void Usage()
    {
        Thread Thing1, Thing2;

        OrderManager OM = new OrderManager();

        OM.Storage = new Dictionary<int, LockEncapsulator<Order>>();

        OM.Storage.Add( 1001, new LockEncapsulator<Order>( new Order( 1001 ) ) );
        OM.Storage.Add( 1002, new LockEncapsulator<Order>( new Order( 1002 ) ) );

        Thing1 = new Thread( Thing1Work );
        Thing2 = new Thread( Thing2Work );

        Thing1.Start( OM.Storage[1001] );
        Thing2.Start( OM.Storage[1001] );

        Thing2.Join();


    }

    static void Thing1Work( object obj )
    {
        LockEncapsulator<Order> le = obj as LockEncapsulator<Order>;
        if (le != null)
        {
            Order or = le.InstanceGet();

            or.PrintOrder( "Thing 1" );

            Thread.Sleep( 5000 );

            le.InstanceReturn();

        }

    }

    static void Thing2Work( object obj )
    {

        LockEncapsulator<Order> le = obj as LockEncapsulator<Order>;
        if (le != null)
        {
            Order or = le.InstanceGet();

            or.PrintOrder( "Thing 2" );

            le.InstanceReturn();

        }
    }
}

To use this and test this OrderManger class, simply call the static Usage() and it will be done. The following is outputted by the threads:

Order 1001 accessed by Thing 1
Order 1001 accessed by Thing 2

Notes

  • Even if Thing2 gets activated by the system before Thing1…no harm at all.
  • Each Thread must call InstanceReturn or Deadlocks will occur. That is the downside…
Share

Smart Resource Locking in C# .Net for Thread Safe Code

Updated 1/8/2012: Removed code formatting to use SyntaxHighlighter and fixed off colors on titles.

So you are into thread safe code and you have begun to lock resources. But the trap that all new programmers sometimes do is to lock the whole class as shown below:

public void DeadlockWaitingToHappen1(string change) 
{     
   lock (this)     
   {         
      _Resource1 = change;     
   } 
} 

public void DeadlockWaitingToHappen2(string change2) 
{     
   lock (this)     
   {         
      _Resource2 = change2;     
   } 
}

The problem with the above code, albeit trite due to the example, is that when a thread 1 calls the first method to change resource1, it will effectively block any other thread calling the opposite method to change _resource2.

Because we know that these resources are independent, such locking in the above case is a nuance, in a more advanced state, causes undo wait times for resources, but in a worse case scenario could cause deadlocks in code!

Solution

To get around that what we will do is to lock separate objects. The below code will create mirror object locks and use those to properly lock our different distinct resources.

// This class simulates the use of two different 
// thread safe resources and how to lock them 
// for thread safety but not block other 
// threads getting different resources. 
public class SmartLocking
{
    private string StrResource1 { get; set; }
    private string StrResource2 { get; set; }

    private object _Lock1 = new object();
    private object _Lock2 = new object();

    public void DoWorkOn1( string change )
    {
        lock (_Lock1)
        {
            _Resource1 = change;
        }
    }

    public void DoWorkOn2( string change2 )
    {
        lock (_Lock2)
        {
            _Resource2 = change2;
        }
    }
}

Summary

As you can see we have separate locks, so now thread 1 accessing resource 1 won’t block thread 2 accessing resource 2.  Note if the object you are working contains the interface to allow locking and it makes sense to use that resource, then lock it instead of a separate object.

Share

Spike Your CPU’s Processor in .Net

This code demonstrates the ability to potentially choose your processor for which your .Net code’s thread can run on. I say that potentially, because the system at anytime can swap out the thread to the other CPU(s).

Background

I had seen an application provide the ability to specify a CPU’s processor. That application was the old Seti@AtHome PC console application used to find alien signals from the galaxy.

Using that CPU setting, I would set it up to run on Xeon machines with four processors and have a separate seti work unit run on each of the four CPU’s. (Doing tricks like that I was able to process 30,000 seti units over the span of six years which equated to 28 years of computer time. Look for OmegaMan in the fifth position). But I digress…

So I knew that this could be done, at least in win32 code, and I had seen MSDN forum posts, where questions would arise,  

“Can I specify a CPU in my .Net app if I have a multi-processor machine?”

Now for those in the know the reason to attach to a cpu doesn’t really buy one much and its best to leave the thread CPU allocation to the OS…but that doesn’t mean one can’t do it.

My Example Application

The following C# code will spike each CPU in unison, if the machine is a multi-processing machine (yes single core hyper threaded machines will work). The code runs a thread on a target CPU with a task of figuring out PI to 750 digits. (See my article entitled Calculate PI using C# which gives the class which will do the calculation. This code is not shown in this article) which spikes the target CPU. I could have done other busy waiting…but PI is somehow, more noble and seemed to be an appropriate task. Here is what it looks like when run. Notice that the primary core spiked first followed by the next. (Picture taken on a Hyper-Threaded machine, so the second is the logical processor).

image

Code

Now to achieve this magic we are going to set the way back machine to include some System 32 functions and threading. Here are the required usings:

using System.Threading;
using System.Runtime.InteropServices;

within our class we will specify the Kernal 32’s methods we are interested in

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
[DllImport("kernel32.dll")]
static extern IntPtr SetThreadAffinityMask(IntPtr hThread, IntPtr dwThreadAffinityMask);

Within the thread here is the code to do the magic:

   1: try
   2: {
   3:     int processor = (int)target;
   4:     Thread tr = Thread.CurrentThread;
   5:  
   6:     if (Environment.ProcessorCount > 1)
   7:     {
   8:         SetThreadAffinityMask(GetCurrentThread(),
   9:             new IntPtr(1 << processor));
  10:     }
  11:  
  12:     CalculatePI.Process(PiSignificantDigits);
  13: }
  14: catch (Exception ex)
  15: {
  16:     _ex = ex;
  17: }

 

  • Line 03:  The target is a zero based number to specify the processor in sequence.
  • Line 08:  This function will specify which CPU to run on. It works with the Affinity Mask which we will set.
  • Line 09:  We shift the mask over to show which processor we want.
  • Line 12:  Here is where we do the work on hopefully the target cpu.

That should do it!

We have specified the thread to run on the target CPU. Here is the full code for your perusal.

Full Code

Note to use the code, call the static function on the class Usage() which will do/demonstrate how to use the class. Also the Calculation of Pi can be found here (Calculate PI using C#), otherwise you will need to do busy work which will spike the CPU.

using System.Threading;
using System.Runtime.InteropServices;
// Target a specific processor for the thread to run on
public class ThreadProcessor
{
    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentThread();
    [DllImport("kernel32.dll")]
    static extern IntPtr SetThreadAffinityMask(IntPtr hThread, IntPtr dwThreadAffinityMask);
 
    public static void Usage()
    {
        int cpu = 0;
        ThreadProcessor tp = new ThreadProcessor();
        Console.WriteLine("Spike CPU 1");
        tp.SpikeCPU(cpu);
 
        if (tp._ex != null)
        {
            Console.WriteLine(tp._ex.Message);
        }
        else
        {
 
            if (Environment.ProcessorCount > 1)
            {
                while (++cpu < Environment.ProcessorCount)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("Spike CPU " + (cpu + 1).ToString());
                    tp.SpikeCPU(cpu);
 
                    if (tp._ex != null)
                    {
                        Console.WriteLine(tp._ex.Message);
                        break;
                    }
                }
 
            }
            else // Either a single CPU or hyperthreading not enabled in the OS or the BIOS.
            {
                Console.WriteLine("This PC does not have two processors available.");
            }
        }
 
    }
 
    private Thread _worker;
    private const int PiSignificantDigits = 750; // Adjust to your processor
 
    // Spike the CPU and waith for it to finish
    public void SpikeCPU(int targetCPU)
    {
 
        // Create a worker thread for the work.
        _worker = new Thread(DoBusyWork);
 
        // Background is set so not to not prevent the
        // mainprocess from terminating if someone closes it.
        _worker.IsBackground = true;
 
        _worker.Start((object)targetCPU);
        _worker.Join(); // Wait for it to be done.
    }
 
 
    public void DoBusyWork(object target)
    {
        try
        {
            int processor = (int)target;
            Thread tr = Thread.CurrentThread;
 
            if (Environment.ProcessorCount > 1)
            {
                SetThreadAffinityMask(GetCurrentThread(),
                    new IntPtr(1 << processor));
            }
 
            CalculatePI.Process(PiSignificantDigits);
        }
        catch (Exception ex)
        {
            _ex = ex;
        }
 
    }
 
    public Exception _ex = null;
 
 
}
Share

C#: Having One Instance Of an Running Application Using A Mutex in System.Threading

(Updated April/9/2011: Removed bad highlight colors, made title more descriptive and reworked wording of the text.)

The following C# code effectively allows for only one instance of an application to run and can be used with any version of .Net.

By using and checking the status of a named mutex the code is assured that another instance is running if its status comes back as valid. Do not check and throw away the mutex for the caveot to doing this is that the mutex could be garbaged collected if not properly held for the lifetime of the application and once the mutex is released another program checking will not find it.

Place a reference to the mutex on an existing long running class or in a static instance in your prgram.

Here is the code, it is demonstrated to run in a console application and the System.Threading namespace must be used:

bool NoInstanceCurrently; // If true we can run otherwise false means another instance is running.

Mutex mutex = new Mutex(false, // Should we be the owner no
                        "Jabberwocky", // Name of the mutex.
                        out NoInstanceCurrently); // Flag to tell us if it exists.

if (NoInstanceCurrently == true)
   {
      Console.WriteLine("Press Enter to kill first instance");
      Console.ReadLine();
   }
else
   {
      Console.WriteLine("Another Instance is Running");
   }
Share

How to handle a .Net 2/3 Abort Exception in Threading

There are circumstances that dictate stopping a thread while it is processing. The first thing a user does is to reach for the atomic bomb of an option Thread.Abort() which if called from a different thread interrupts all operations be done. (Note if it is called within the thread itself, it is like throwing an exception and the below problems do not exist.)

Problems

Abort() can cause insidious problems within managed code. The cancel will jerk the function pointer out of whatever operations are currently executing. When that happens in the .Net internals it can disrupt specific states and operations that should have been carried out but will be left in an unknown state. When future code, even in other threads, uses that functionality, the improper state will cause problems. when similar processes try to use that functionality it may behave in unpredictable ways.

Anything But Abort

Before using Thread.Abort consider checking a common variable in the worker process which will indicate that things should be stopped. The worker will check the flag and exit immediately. That will be cleaner and will not introduce the problems that Abort may do.

But if You Do

Regardless of whether one intends to call Abort or not, one should handle the abort exception ThreadAbortException. Note in the code below we call ResetAbort to stop the exception from be propagated. In a sense, we could pick up and restart, but since this is a cancel, no sense in fighting it. Here is a snippet to handle the exception properly.

try
 { 
   // Work is done here   
 }
 
 // Catch this exception if the parent calls thread.abort()
 // So we handle a cancel gracefully.
 catch (ThreadAbortException)
 {
     // We have handled the exception and will simply return without data.
     // Otherwise the abort will be rethrown out of this block.
     Thread.ResetAbort();
 
     // Posibly set a state for any consumers.
 }
Share

.Net Thread Communication (.Net 2/3)

Share