net mobile application development concurrency in distributed clients

34
.NET Mobile Application Development Concurrency in Distributed Clients

Post on 21-Dec-2015

227 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: NET Mobile Application Development Concurrency in Distributed Clients

.NET Mobile Application Development

Concurrency in Distributed Clients

Page 2: NET Mobile Application Development Concurrency in Distributed Clients

Introduction

Concurrency occurs in all distributed systems Controlling concurrency is essentially to developing

scalable, correct distributed applications

In this session and the next we will consider > Multi-threading and concurrency

> Concurrency in distributed clients

> Concurrency control mechanisms

Page 3: NET Mobile Application Development Concurrency in Distributed Clients

Concurrency in Distributed Applications

Distributed applications are inherently concurrent> Services have to deal with multiple simultaneous clients in a scalable

manner

> Clients may need to perform multiple simultaneous activities

Accept user input and use services

Concurrency needs to be used and managed correctly to avoid

> Performance penalties

> Incorrect operation and sequencing of activities

Page 4: NET Mobile Application Development Concurrency in Distributed Clients

Concurrency in Distributed Clients

Concurrency is mainly used in distributed clients to overcome latencies resulting from distributed interactions

This has several benefits> Increased client performance

Client can perform other activities / processing whilst remote interactions proceed

> Increased client responsiveness and improved user experience

User interface does not freeze when remote interactions or lengthy computations occur

Application responds to user input in a timely manner

Page 5: NET Mobile Application Development Concurrency in Distributed Clients

Multithreading

Thread> An independent unit of program execution

Multithreaded program> Multiple threads execute simultaneously

Threads multiplexed onto available CPU’s using timeslicing Context switch incurs (minor) overhead

> Threads exist in the same process and share common address space

Multithreading > can improve performance only when there is an operation with some latency

the longer the delay, the greater the potential performance benefit from using threads

> will not improve performance if threads are competing for finite (e.g. CPU) resources; multithreading will actually result in worse performance

Page 6: NET Mobile Application Development Concurrency in Distributed Clients

Threading Issues

Multithreading can improve performance Multithreading will introduce

> additional complexity> unusual errors that are difficult to detect, replicate and debug > additional overhead; OS must manage all the threads

Getting threading right is difficult; need to> use synchronization and locking to ensure correct interleaving of thread

operations and interactions> balance potential improvements from threading against additional

overheads (number of threads)> avoid deadlock, livelock, race conditions, etc caused by incorrect /

insufficient / too much synchronization

Page 7: NET Mobile Application Development Concurrency in Distributed Clients

Threading in .NET

Can use threads in .NET by> Using .NET types with built-in threading support

Types that support asynchronous operation (i.e. has Begin? and End? methods)

Windows forms types through the Invoke() method> Manually creating and manipulating threads using the System.Threading.Thread type

Page 8: NET Mobile Application Development Concurrency in Distributed Clients

Using Asynchronous Delegates

A delegate is> a type-safe pointer to a method (function pointer)

> an instance of the Delegate type

Delegate type has two important methods> BeginInvoke()

invokes the method referred to by the delegate on a separate thread

immediately returns an IAsyncResult instance and allows calling thread to continue

> EndInvoke()

allows retrieval of results from a method invoked earlier using BeginInvoke()

needs to be given IAsyncResult instance returned by BeginInvoke()

Page 9: NET Mobile Application Development Concurrency in Distributed Clients

Asynchronous Delegate Example

delegate int MyDelegate(int i, int j);

class Program { public static void Main() {

Maths m = new Maths();

// Create the delegate - note that BeginInvoke always takes 2 extra parametersMyDelegate dlgt = new MyDelegate(m.Add);// Asynchronosly invoke itIAsyncResult iar = dlgt.BeginInvoke(2, 2, null, null);

// Do something else whilst call progresses

// Wait for async method to complete and retrieve the results int result = dlgt.EndInvoke(iar);

}}

class Maths {public int Add(int a, int b) {

return a+b;}

}

Criticisms•EndInvoke() call blocks if method invoked by delegate not yet completed•Can poll for completion using the IAsyncResult instance•Neither option is good

Page 10: NET Mobile Application Development Concurrency in Distributed Clients

Using Callbacks

Callback > method called when an asynchronously invoked delegate completes its

operation Callbacks

> eliminate inefficient polling > simplify coding

Callback method> signature must match System.AsyncCallback delegate type > AsyncCallback instance referencing desired callback method must be

passed to BeginInvoke()> callback is passed an IAsyncResult object when it is invoked

use this to call EndInvoke() and retrieve results

Page 11: NET Mobile Application Development Concurrency in Distributed Clients

Asynchronous Callback Example

delegate int MyDelegate(int i, int j);

class Program{ static MyDelegate dlgt;

public static void Main() {Maths m = new Maths();AsyncCallback cdlgt = new AsyncCallback(MyCallback);dlgt = new MyDelegate(m.Add);

// Penultimate BeginInvoke() parameter is callback delegateIAsyncResult iar = dlgt.BeginInvoke(2, 2, cdlgt, null);Console.ReadLine(); // Do something else

}

public static void MyCallback(IAsyncResult iar) {int result = dlgt.EndInvoke(iar); // Use IAsyncResult instance to retrieve the results

}}

class Maths {public int Add(int a, int b){ return a+b; }

}

NOTE: •Callback method executes on yet another thread

Page 12: NET Mobile Application Development Concurrency in Distributed Clients

Advantages of Asynchronous Invocation

Implicitly using threads by using asynchronous invocation has several advantages

> environment takes care of creating and managing all threads for us

> no need for explicit concurrency control operations

> improves performance by enabling long-running tasks to be started without stalling application

Asynchronous invocation not suitable for> code which needs to communicate between threads

> applications which need to prioritize threads

> this requires manual thread creation

Page 13: NET Mobile Application Development Concurrency in Distributed Clients

Creating .NET Threads

Threads are created by> declaring a method which will be the body of the thread

must be of return type void and accept no parameters can call any other methods

> creating a ThreadStart delegate instance which refers to this method > creating a new Thread object, passing it the delegate> calling Thread.Start()

System.Threading.Thread > is the primary type used for managing threads > allows threads to be created, started, stopped, suspended, resumed,

joined, delayed, etc

Page 14: NET Mobile Application Development Concurrency in Distributed Clients

Custom Threading Example

class Program{ public static void Main() {

// Create the threadsThread tA = new Thread(new ThreadStart(TaskA));Thread tB = new Thread(new ThreadStart(TaskB));tA.Start(); // Start the threadstB.Start();Console.ReadLine(); // Pause until user presses key

}

private static void TaskA() {for (int i = 0; i < 10; i++) {

Console.WriteLine("Task A at: "+i);WasteTime(1000); }

}

private static void TaskB() {for (int i = 0; i < 10; i++) {

Console.WriteLine("Task B at: "+i);WasteTime(1000); }

}}

Page 15: NET Mobile Application Development Concurrency in Distributed Clients

Thread Priorities

Threads are selected for execution based on their priority> highest priority execute first, lowest priority last

All threads created equally with default normal priority> priority can be adjusted via Thread.Priority property

> five relative priority levels supported

Lowest, Below Normal, Normal, Above Normal, Highest

Setting thread priorities correctly is important> giving a thread too high a priority can lead to starvation of other threads

Page 16: NET Mobile Application Development Concurrency in Distributed Clients

Thread Priority Example

class Program{ public static void Main() {

Thread tA = new Thread(new ThreadStart(TaskA));Thread tB = new Thread(new ThreadStart(TaskB));

tA.Priority = ThreadPriority.AboveNormal; tB.Priority = ThreadPriority.Normal;tA.Start(); tB.Start(); // Start the threadsConsole.ReadLine(); // Pause until user presses key

}

private static void TaskA() {for (int i = 0; i < 10; i++) {

Console.WriteLine("Task A at: "+i);WasteTime(1); }

}

private static void TaskB() {for (int i = 0; i < 10; i++) {

Console.WriteLine("Task B at: "+i);WasteTime(1); }

}}

Page 17: NET Mobile Application Development Concurrency in Distributed Clients

Threaded Clients

Any operation which will take a long time to complete or adversely affect application responsiveness is a good candidate for executing on a separate thread

e.g. Windows Media Player 9> Info Center View takes time to retrieve data from the Internet> executing this on separate thread from user interface allows user to

control playback in the meantime> when data is returned from Internet, UI can be appropriately

updated

Page 18: NET Mobile Application Development Concurrency in Distributed Clients

User Interfaces in .NET Threaded Clients

Windows Forms controls in a .NET application > are not thread safe> can only be safely operated upon by the thread which owns them

Consider the Windows Media Player example with a thread which fetches data from the Internet. This thread

> is separate from the UI thread> should not update the application’s UI as it is not the owner of the UI

controls

Page 19: NET Mobile Application Development Concurrency in Distributed Clients

Win Forms and Threading

Windows.Forms.Control base class provides an Invoke() method which is passed a delegate to another method

> Delegate must be of type MethodInvoker

Delegated method acts as a callback used to update the relevant control

Calling Invoke() causes the delegated update method to be safely invoked on the User Interface thread which owns the control

Page 20: NET Mobile Application Development Concurrency in Distributed Clients

WinForms Threading Example

Simple Form application with two threads> UI thread created by Application.Run()> separate thread used to periodically increments counter> button controls operation of counter thread

UIUpdater() displays latest count value in lblCount Label

Counter thread > creates delegate to UIUpdater() > calls lblCount.Invoke() with this delegate each time it wishes

to update the count value in the UI

Page 21: NET Mobile Application Development Concurrency in Distributed Clients

Concurrency Control

Two key aspects to concurrency control Mutual exclusion

> Preventing object / resource from being accessed by more than one thread at once

> Needed to prevent corruption of state in presence of multiple client updates

> Implemented through locking

Synchronization> Imposes order on interleaving of operations of multiple threads (usually for

correctness)

> Implemented using semaphores, condition variables or monitors

Page 22: NET Mobile Application Development Concurrency in Distributed Clients

Condition Synchronization

Needed when a thread wishes to perform an operation which can only sensibly(safely) be performed if another thread has itself taken some other action or is in some defined state

Example : A bounded buffer has 2 condition synchronization

> producer thread must not attempt to put data in buffer if it is full

> consumer thread must not attempt to get data from buffer if it is empty

> Is mutual exclusion necessary?

Page 23: NET Mobile Application Development Concurrency in Distributed Clients

Locks and Mutual Exclusion

Critical Section - a sequence of statements that appear to execute indivisibly

Mutual Exclusion - synchronization required to protect a critical section

Locks - implement mutual exclusion and guard critical sections

> Code construct which marks a critical section of code that must be executed under mutual exclusion

Page 24: NET Mobile Application Development Concurrency in Distributed Clients

Locking

In an OO environment, every object has an associated lock

Lock construct specifies the object on which the lock should be obtained

First thread to execute the lock statement will be granted the lock and can execute protected section of code

> Whilst first thread has the lock, any other threads executing the lock statement will block until lock is released. Waiting threads will then compete for the lock.

Page 25: NET Mobile Application Development Concurrency in Distributed Clients

Example: Locking in C#

int Withdraw(int amount)

{

lock (this)

{

if (balance >= amount) {

Console.WriteLine("Balance before Withdrawal : " + balance);

Console.WriteLine("Amount to Withdraw : -" + amount);

balance = balance - amount;

Console.WriteLine("Balance after Withdrawal : " + balance);

return amount;

}

else {

return 0; // transaction rejected

}

}

}

Page 26: NET Mobile Application Development Concurrency in Distributed Clients

Locking - Disadvantages

Locking is essential to preventing conflicting updates but can adversely affect performance

If scope of lock is too great> forces some threads to wait

> decreases potential concurrency and throughput / performance

If scope of lock is too small> forces reacquisition of locks, leading increased lock contention and

reduced throughput / performance

> can result in difficult-to-debug race conditions

Page 27: NET Mobile Application Development Concurrency in Distributed Clients

Advanced Locking

Mutual exclusion> not needed if all threads are reading values> needed if at least one thread is writing values

ReaderWriter lock > allows concurrent read access for multiple threads, or > write access for a single thread > uses separate locks for readers and writers; clients must specify

which lock they want

Page 28: NET Mobile Application Development Concurrency in Distributed Clients

Advanced Locking Example

ReaderWriterLock rwl = new ReaderWriterLock();

void ReadFromResource(int timeOut) { try { rwl.AcquireReaderLock(timeOut); try {

/ Safe for this thread to read from // the shared resource. } finally {

// Ensure that the lock is released. rwl.ReleaseReaderLock(); } } catch (ApplicationException) { // The reader request timed out. }}

void WriteToResource(int timeOut) { try { rwl.AcquireWriterLock(timeOut); try { // It is safe for this thread to read // or write from the shared resource. } finally {

// Ensure that the lock is released. rwl.ReleaseWriterLock(); } } catch (ApplicationException) { // The writer lock request timed out. }}

Page 29: NET Mobile Application Development Concurrency in Distributed Clients

Monitors

Monitor > code construct that provides both mutual exclusion and condition

synchronization> acts like a ‘smart’ lock

Thread enters the monitor and attempts to acquire lock

> if successful, thread executes under mutual exclusion; thread frees lock when finished

> if unsuccessful, thread blocks until monitor is available

Page 30: NET Mobile Application Development Concurrency in Distributed Clients

Monitors: Condition Synchronisation

When inside a monitor, condition variables can be used

> Thread can Wait() on condition variable thread blocks and releases lock, freeing monitor to other

threads when condition becomes true, thread unblocks, reacquires lock

and executes under mutual exclusion> Thread can Signal() a condition variable

notifies waiting threads that condition is true teleases lock, freeing monitor to other threads

Page 31: NET Mobile Application Development Concurrency in Distributed Clients

.NET Monitors Example

public class MyClass{private object x;

public void DoSomething() { Monitor.Enter(x); try { // Code that needs protected by the monitor.

// Monitor.Wait and Monitor.Pulse can be// used in here

} finally { // Ensure that you exit Monitor.

Monitor.Exit(x); }}

Page 32: NET Mobile Application Development Concurrency in Distributed Clients

Common Concurrency Problems

Two common problems Deadlock

> A situation where two or more threads are unable to proceed because each is waiting for the others to do something

> Avoid by always acquiring / releasing locks in the same order ensuring that all Wait()’s have a matching Signal()

Race Conditions> Anomalous behaviour due to unexpected critical dependence on the relative

ordering of operations> Can occur is scope of locks is too small and some code left outside critical sections

These problems are> Easy to unwittingly introduce> Difficult to detect and remove

Page 33: NET Mobile Application Development Concurrency in Distributed Clients

In this session we have discussed> The role of concurrency in distributed clients

> Multi-threading and thread management in .NET

> Asynchronous invocation and callback

> Locks, monitors and performance

> Alternative thread coordination mechanisms

Summary

Page 34: NET Mobile Application Development Concurrency in Distributed Clients

Reading and Resources

Reading Coulouris, Dollimore & Kindberg, Distributed Systems:

Concepts and Design, 3rd Edition, Addison-Wesley, 2001Chapter 12, pp 465 – 514

MacDonald, Microsoft .NET Distributed Applications: Integrating XML Web Services and .NET Remoting, Microsoft Press, 2003

Chapter 6, pp 175 – 220