lecture 4 thread concepts. thread definition a thread is a lightweight process (lwp) which accesses...

19
Lecture 4 Thread Concepts

Upload: christina-caldwell

Post on 18-Dec-2015

232 views

Category:

Documents


2 download

TRANSCRIPT

Lecture 4

Thread Concepts

Thread Definition

A thread is a lightweight process (LWP) which accesses a shared address space provided by by the parent process. Each thread keeps its own state parameters and register values so that it may run concurrently with other threads. Threads may be managed by the OS (kernel-level threads) or by a user application (user-level threads).

2004 Deitel & Associates, Inc.

Threads vs. Processes

Processes each have their own address space, text space and resources, while threads spawned within a user application all share the memory and resources of the parent thread or process. A thread defines a single sequential execution stream within a process. Each thread maintains its own PC, SP and CPU register values.

Thread States

2004 Deitel & Associates, Inc.

Thread Operations

Threads have some operations in common with processes

Create Exit (terminate)Suspend ResumeSleep Wake

Other thread operations do not correspond to process operations

Cancel - indicates that a thread should be terminated, but does not guarantee that the thread will be terminated. Threads can mask the cancellation signal.

Join - a primary thread can wait for all other threads to exit by joining them. The joining thread blocks until the thread it joined exits.

2004 Deitel & Associates, Inc.

User-Level Threads

A user-level thread is one that is created and managed by a user application. Usually the OS does not know of the existence of user-level threads so additional resources are not provided by the OS for user-level threads. Each user-level thread must share the resources already allocated to the user application.

2004 Deitel & Associates, Inc.

Kernel-Level Threads

Kernel-level threads are created and managed by the OS. They attempt to address the limitations of user-level threads by mapping each thread to its own execution context. Kernel-level threads offer increased scalability, interactivity, and throughput, but have a higher overhead due to context switching and reduced portability because of OS-specific APIs

2004 Deitel & Associates, Inc.

• to utilize a multiprocessor for parallel operations

• to do useful work while waiting for a slow device

• to satisfy human users by working on several actions at once

• to provide network service to multiple clients simultaneously

• to defer work until a less busy time

• to implement a pipeline process

Multi-Threading Applications

An Introduction to Programming with C# Threads - Andrew D. Birrell

using System;using System.Threading;namespace first_thread_demo{ public class Version_1 { public static bool done = false;

public static void T1() { System.Random rnd = new Random(); while (!done) { Console.WriteLine("T1 in critical section"); Thread.Sleep(rnd.Next(100)); Console.WriteLine("T1 is leaving critical section"); } }

static void Main(string[] args) { Thread p = new Thread(new ThreadStart(T1)); p.Start(); Thread q = new Thread(new ThreadStart(T2)); q.Start(); Thread.Sleep(5000); done = true; Console.WriteLine("Run Finished"); Console.ReadKey(); } }}

public static void T2() { System.Random rnd = new Random(); while (!done) { Console.WriteLine("T2 in critical section"); Thread.Sleep(rnd.Next(100)); Console.WriteLine("T2 is leaving critical section"); } }

A Simple Multi-Threading Demo

T2 is leaving critical sectionT2 in critical sectionT1 is leaving critical sectionT1 in critical sectionT2 is leaving critical sectionT2 in critical sectionT1 is leaving critical sectionT1 in critical sectionT1 is leaving critical sectionT1 in critical sectionT2 is leaving critical sectionT2 in critical sectionT1 is leaving critical sectionT1 in critical sectionT2 is leaving critical sectionT2 in critical sectionT1 is leaving critical sectionT1 in critical sectionT1 is leaving critical sectionT1 in critical sectionT2 is leaving critical sectionT2 in critical sectionT1 is leaving critical sectionT1 in critical sectionT2 is leaving critical sectionT2 in critical sectionT1 is leaving critical sectionT1 in critical section

BothT1 & T2 can be in Critical Sections at the Same Time

public static int threadnumber = 1; :public static void T1(){ System.Random rnd = new Random(); while (!done) { while (threadnumber == 2); Console.WriteLine("T1 in critical section"); Thread.Sleep(rnd.Next(100)); Console.WriteLine("T1 is leaving critical section"); threadnumber = 2; }}

A "Fix" for the Problem

The inclusion of a globally accessible variable threadnumber that can be set to the number of the preferred thread to execute can prevent two threads from entering their critical sections at the same time, but at what cost?

a very important semicolon

Worker Threadsand the BackgroundWorker Class

A common application for multithreading is performing time-consuming tasks in the background. The main thread keeps running, while the worker thread does its background job.

A C# application can become multi-threaded in two ways:

(1) by explicitly creating and running additional threads, or

(2) using a feature of the .NET framework that implicitly creates threads

• such as BackgroundWorker

• thread pooling,

• a threading timer

• a Remoting server or Web Services

• an ASP.NET application.

Threading in C# Joseph Albahari

BackgroundWorker is a helper class in the System.ComponentModel namespace for managing a worker thread. It provides the following features:

· A "cancel" flag for signaling a worker to end without using Abort

· A standard protocol for reporting progress, completion and cancellation

· An implementation of IComponent allowing it be sited in the Visual Studio Designer

· Exception handling on the worker thread

· The ability to update Windows Forms controls in response to worker progress or completion.

The last two features are particularly useful – it means you don't have to include a try/catch block in your worker method, and can update Windows Forms controls without needing to call Control.Invoke.

BackgroundWorker Class

Threading in C# Joseph Albahari

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

1. Double-click on BackgroundWorker (see link appear below form).

2. Highlight backgroundWorker1 and look at Properties panel.

3. Select events panel (lightning bolt)

4. Double-click on DoWork to create a shell method.

5. Add worker code to this method:

Thread.Sleep(1000);

This statement will cause the worker to wait 1000 milliseconds (to simulate a time-consuming task).

A Simple BackgroundWorker Demo Program

http://dotnetperls.com/backgroundworker

class Program { public static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) threads[i].Start(); Console.ReadKey(); } }}

When Threads Collide

Independently executing threads are relatively easy to implement. Issues of complexity and program correctness arise when threads communicate and/or access shared memory. In this example, ten threads are running concurrently, all accessing the same memory space.

Open a new "account" acc with 1000 "foobucks".

Launch 10 concurrent threads of execution t that make repeated withdrawals from this account

ensure that the account is not overdrawn

using System;using System.Threading;using System.Text;

namespace lock_demo{ class Account { static object locker = new object(); int balance;

Random r = new Random();

public Account(int initial) { balance = initial; }

private int Withdraw(int amount) { if (balance < 0) throw new Exception("Negative Balance");

lock (locker) { 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 } }

public void DoTransactions() { for (int i = 0; i < 100; i++) Withdraw(r.Next(1, 100)); } }

lock( ) Demo

Balance before Withdrawal : 1000Amount to Withdraw : -87Balance after Withdrawal : 913Balance before Withdrawal : 913Amount to Withdraw : -62Balance after Withdrawal : 851Balance before Withdrawal : 851Amount to Withdraw : -28Balance after Withdrawal : 823Balance before Withdrawal : 823Amount to Withdraw : -3Balance after Withdrawal : 820Balance before Withdrawal : 820Amount to Withdraw : -8Balance after Withdrawal : 812Balance before Withdrawal : 812Amount to Withdraw : -32Balance after Withdrawal : 780Balance before Withdrawal : 780Amount to Withdraw : -16Balance after Withdrawal : 764Balance before Withdrawal : 764Amount to Withdraw : -69Balance after Withdrawal : 695Balance before Withdrawal : 695Amount to Withdraw : -29Balance after Withdrawal : 666Balance before Withdrawal : 666Amount to Withdraw : -42Balance after Withdrawal : 624Balance before Withdrawal : 624Amount to Withdraw : -44Balance after Withdrawal : 580Balance before Withdrawal : 580 :

:Amount to Withdraw : -22Balance after Withdrawal : 166Balance before Withdrawal : 166Amount to Withdraw : -26Balance after Withdrawal : 140Balance before Withdrawal : 140Amount to Withdraw : -5Balance after Withdrawal : 135Balance before Withdrawal : 135Amount to Withdraw : -57Balance after Withdrawal : 78Balance before Withdrawal : 78Amount to Withdraw : -14Balance after Withdrawal : 64Balance before Withdrawal : 64Amount to Withdraw : -11Balance after Withdrawal : 53Balance before Withdrawal : 53Amount to Withdraw : -16Balance after Withdrawal : 37Balance before Withdrawal : 37Amount to Withdraw : -20Balance after Withdrawal : 17Balance before Withdrawal : 17Amount to Withdraw : -15Balance after Withdrawal : 2Balance before Withdrawal : 2Amount to Withdraw : -1Balance after Withdrawal : 1Balance before Withdrawal : 1Amount to Withdraw : -1Balance after Withdrawal : 0

Results with lock( )

Balance before Withdrawal : 1000Amount to Withdraw : -82Balance after Withdrawal : 918Balance before Withdrawal : 918Amount to Withdraw : -33Balance after Withdrawal : 885Balance before Withdrawal : 885Amount to Withdraw : -53Balance after Withdrawal : 832Balance before Withdrawal : 832Amount to Withdraw : -18Balance after Withdrawal : 814Balance before Withdrawal : 814Balance before Withdrawal : 1000Amount to Withdraw : -94Balance after Withdrawal : 720Balance before Withdrawal : 720Amount to Withdraw : -68Balance after Withdrawal : 652Balance before Withdrawal : 652Amount to Withdraw : -50Balance after Withdrawal : 602Balance before Withdrawal : 602Amount to Withdraw : -16Balance after Withdrawal : 586Balance before Withdrawal : 586Amount to Withdraw : -81Balance before Withdrawal : 720Amount to Withdraw : -35Balance after Withdrawal : 470Balance before Withdrawal : 470Amount to Withdraw : -97Balance after Withdrawal : 373Amount to Withdraw : -98Balance after Withdrawal : 275 :

:Balance before Withdrawal : 152Amount to Withdraw : -26Balance before Withdrawal : 152Balance before Withdrawal : 275Balance before Withdrawal : 275Amount to Withdraw : -3Balance after Withdrawal : 123Balance before Withdrawal : 126Amount to Withdraw : -49Balance after Withdrawal : 74Balance before Withdrawal : 126Amount to Withdraw : -71Balance after Withdrawal : 3Amount to Withdraw : -2Amount to Withdraw : -55Balance after Withdrawal : 126Balance after Withdrawal : 1Balance before Withdrawal : 1Balance before Withdrawal : 74Amount to Withdraw : -63Balance before Withdrawal : 123Balance before Withdrawal : 74Balance after Withdrawal : -54Amount to Withdraw : -59Balance after Withdrawal : -176Balance after Withdrawal : -117Amount to Withdraw : -1Amount to Withdraw : -71Balance after Withdrawal : -248Amount to Withdraw : -54Balance after Withdrawal : -177Balance after Withdrawal : -302

Results without lock( )

Summary

A thread is a lightweight process

Two or more threads spawned within an application share memory space

User-level threads are controlled by the parent process

Kernel-level threads are controlled by the OS

There are many reasons to build a multithreaded application

Multiple threads running independently are easy to implement

Effective (and error-free) thread communication and/or interaction is difficult

Concurrent (i.e. asynchronous) operation means

"order of execution between threads is indeterminate"