Download presentation
Presentation is loading. Please wait.
Published byJustin Conley Modified over 9 years ago
1
Windows Programming Using C# Threading
2
2 Contents Threading Thread class Interlocked class Monitor class Semaphore class Thread Pools
3
3 Threading A thread is a lightweight process A process runs directly under the operating system Each process has its own private memory A thread shares memory with other threads Threads run concurrently or pseudo- concurrently
4
4 Threading Pseudo-parallelism is simulated by switching the processor rapidly between threads Threads allow a program to appear to do several things at once This is vital for many modern programming tasks
5
5 Threading.NET supports threading with the System.Threading namespace This contains classes which allow for the creation and synchronization of concurrent threads
6
6 Thread Class The Thread class is the class which creates new threads The simplest way to create a thread is to pass a parameterless, void method to the constructor Thread t = new Thread(doWork); Where doWork() is a void method which does all of the work of the thread
7
7 Thread Class The new thread will start to run once you call t.Start(); The thread will continue to run until The method for the thread exits t.Abort() is called t.abort() throws a ThreadAbortException which can be caught to perform a cleanup before the thread terminates
8
8 Thread Class A thread can be put to sleep for a period This will mark the thread as not runnable until the period has elapsed t.Sleep(int milliseconds) Causing a thread to sleep can be used as A primitive timer A way to simulate randomly occurring events
9
9 Thread Class Often, you want to block the current thread until one or more other threads complete This can be used with the join() method t.join(); If you are unsure how long the thread will take, you can specify a timeout t.join(int milliseconds) This will block until the thread terminates or the timeout elapses
10
10 Thread Properties Name A name for the thread which can be set or retrieved IsAlive True if the thread has started and has not terminated or aborted CurrentThread Returns a reference to the currently executing thread
11
11 Thread Properties IsBackground Returns true if this is a background thread Can also be set to true or false a thread can be foreground or background Foreground The process containing foreground threads cannot terminate until all foreground threads have terminated Background A process can terminate even if background threads in the process are still alive
12
12 Shared Data Threads can perform on their own unless they have to access data shared by another thread You cannot tell when one thread will stop and another will start If one thread is halfway through updating shared data and is suspended, another thread will access the half-updated data This results in data corruption
13
13 Atomic Operations In order to prevent data corruption, operations on shared data must be atomic This means the thread executing the operation cannot be interrupted until the operation is finished A section of code which cannot be interrupted is called a critical section
14
14 Interlocked Class This is a lightweight class which provides atomic operations on simple integers and floating points All methods of the class are static Methods int Add(ref int loc, int value) Adds value to loc and returns the new value of loc
15
15 Interlocked Class int increment(ref int loc) Adds 1 to the location and returns the new value int decrement(ref int loc) Subtracts 1 from the location and returns the new value int CompareExchange(ref int loc, int value, int comparand) Compares the value in loc to comparand and if equal assigned value to loc. The original value for loc is returned.
16
16 Monitor Class The monitor provides a high-level, easy to use synchronization model A lock is obtained on an object Once a thread obtains the lock, it has exclusive access to the object until the lock is released This creates a critical section while a thread holds the lock on an object
17
17 Monitor Class To enter a critical section Monitor.Enter(object); This obtains a lock on the object No other thread may obtain a lock on this object while one thread is holding the lock To release the lock Monitor.Exit(object); This releases the lock at the end of the critical section
18
18 Monitor Synchronization Monitors allow two or more threads to synchronize their operations This requires that the two threads be able to communicate The monitor provides three methods for inter- thread communication bool Wait(object) void Pulse(object) void PulseAll(object)
19
19 Monitor Synchronization You acquired a lock on the object You test the object state and it is not what you want You want to release the lock and reacquire it as soon as the state changes Monitor.Wait(object); Releases the lock Blocks until the lock is reacquired Returns true when the lock is reacquired
20
20 Monitor Synchronization Another thread holds the lock and has modified the object so that it is ready for use by another object It calls Pulse(object); This moves the next thread waiting on the lock to the ready queue That thread will run after a while and can obtain the lock
21
21 Monitor Synchronization Note: Only the thread which holds the lock can call Wait() Only the thread which holds the lock can call Pulse() These restrictions mean that calls to Wait() and Pulse() must occur within critical sections
22
22 The Wait/Pulse Advantage A thread is waiting for an object to change state One way to program this is Acquire lock While(object not in desired state) {} Work on object Release lock This is called busy waiting and is VERY inefficient
23
23 The Wait/Pulse Advantage The previous code will not work since it never releases the lock to let another thread change the object state If we provide a method on the object which is synchronized and returns the state, we can make this method better while(obj.State() != READY) {} Acquire lock Do work Release lock
24
24 The Wait/Pulse Advantage The problem with this solution is that once the right state is obtained, another thread might get the lock before you do There is also the problem that your look is using CPU time in large amounts Wait/Pulse provides a solution by blocking the waiting thread until it is unblocked by a call to Pulse
25
25 Blocking Queue A blocking queue is a queue which Can add objects to the tail of the queue Can remove objects from the head of the queue Since both operations modify the queue, they have to synchronized If the queue is empty, the remove operations should block until data becomes available The add operation should notify waiting threads that data is ready to be removed from the queue
26
26 Blocking Queue Producing Thread Blocking Queue Consuming Thread Wait() Pulse()
27
27 Blocking Queue public class BlockingQueue { Object[] que;// queue of objects int queSize;// size of the queue int first, last;// index of first and last members public BlockingQueue(int maxLen) { que = new object[maxLen]; queSize = maxLen; first = 0; last = 0; } … } *see blocking_queue
28
28 Blocking Queue public bool add(object o) { Monitor.Enter(this);// acquire lock if((last + 1) == first) { return false; } que[last] = o; last++; if(last >= queSize) { last = 0; } Console.WriteLine("added {0}", o); Monitor.Pulse(this);// notify waiting threads Monitor.Exit(this);// release lock return true; }
29
29 Blocking Queue public object get() { object result = null; Monitor.Enter(this);// acquire lock if(getSize() == 0) { Monitor.Wait(this);// release lock & wait for notification } result = que[first]; first++; if(first >= queSize) { first = 0; } Monitor.Exit(this);// release lock return result; }
30
30 Testing Blocking Queue class MainClass { BlockingQueue que = new BlockingQueue(50); Thread t1, t2; int n = 10; public MainClass() { t1 = new Thread(new ThreadStart(writer)); t2 = new Thread(new ThreadStart(reader)); t2.Start(); t1.Start(); t1.Join(); t2.Join(); } … }
31
31 Testing Blocking Queue public void writer() { for(int i = 0; i < n; i++) { que.add(i.ToString()); } public void reader() { for(int i = 0; i < n; i++) { object o = que.get(); Console.WriteLine(o); }
32
32 Semaphore Class A semaphore is a simple flag which is on or off Switching a semaphore from one state to another is an atomic operation A counting semaphore is one with more states and can count up to a maximum value
33
33 Counting Semaphores Counting semaphores have the properties A thread requests access to a semaphore If the value is > 0, access is granted and the count is decremented If the value is 0, the thread is blocked until the count becomes > 0 When a thread finishes its work, it can release the semaphore which increments the value and notifies waiting threads
34
34 Using Semaphores Semaphores are useful when there is a pool of shared resources Assume you have 3 tape drives connected to your computer Multiple threads try to write to a tape Only one thread can write to a tape at once Therefore, a semaphore with a maximum value of 3 is used to ensure that each thread has access to exactly one tape drive
35
35 Using Semaphores We can create a new semaphore by Semaphore pool = new Semaphore(count, maxCount); Creates a semaphore with maxCount and an initial value of count A thread which wants access to a semaphore will call pool.WaitOne(); This will block until the semaphore count is greater than zero
36
36 Using Semaphores After a thread has finished with the resource, it can release the semaphore pool.release(); This increments the count by one and notifies waiting threads There is also a special form of release which can release more than one unit pool.Release(n); Releases n units Useful for having the main thread make all units available at the same time *see semaphore_demo
37
37 Thread Pools Threads are scarce resources Your computer can only create so many of them Some types of programming have threads which spend much of their time sleeping or blocked An example is reading a long message from a slow internet server
38
38 Thread Pools Threads which do little work and sleep most of the time are a waste of resources Another point is that on many systems it takes time to create a thread and destroy a thread On these systems it is better to leave the thread sleeping and wake it up only when data arrives for it to handle
39
39 Thread Pools A thread pool is a collection of threads which sleep until work arrives When work arrives, a thread is woken up and dispatched to do the work When the work is done, the thread goes back to the pool and sleeps until it is needed again
40
40 ThreadPool Class The ThreadPool class Implements a thread pool Provides a default of 25 threads per processor Cannot have less than 1 thread per processor Has maximum numbers of threads depending on the hardware platform There is only one ThreadPool per process All ThreadPool methods are static
41
41 ThreadPool Class Methods GetMaxThreads() / Set MaxThreads(n) Returns or sets the max number of threads in the pool GetMinThreads() / Set MinThreads(n) Returns or sets the min number of threads in the pool GetAvailableThreads() Returns the number of threads which are not currently working
42
42 ThreadPool Class QueueUserWorkItem(WaitCallback) Queues some work to be done by the thread pool The work is a method with the signature void Worker(Object stateInfo); The first available thread is dispatched to execute the method The thread returns to the pool when the method ends QueueUserWorkItem(WaitCallback, object) Passes data to stateInfo parameter of worker method
43
43 ThreadPool Class All threads in a ThreadPool are background threads This means that the main thread must wait for the threads in the pool to terminate before the main thread terminates * see pool_demo
44
44 Timer Class The Threading namespace provides a Timer class This class takes a callback and a period in milliseconds Each time the period expires, the callback is invoked To turn a timer off Timer.Dispose();
45
45 Timer Class A callback has the signature void TimerHandler(object info); The info is some data which will be passed by the timer The callback must be a TimerCallback delegate
46
46 Timer Class To create a Timer Timer t = new Timer( new TimerCallback(TimerHandler), null, // info to pass 100, // milliseconds before 1 st call 5000);// period in milliseconds *see timer_demo
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.