Presentation is loading. Please wait.

Presentation is loading. Please wait.

EE4E. C++ Programming Lecture 6 Advanced Topics. Contents Introduction Introduction Exception handling in C++ Exception handling in C++  An object oriented.

Similar presentations


Presentation on theme: "EE4E. C++ Programming Lecture 6 Advanced Topics. Contents Introduction Introduction Exception handling in C++ Exception handling in C++  An object oriented."— Presentation transcript:

1 EE4E. C++ Programming Lecture 6 Advanced Topics

2 Contents Introduction Introduction Exception handling in C++ Exception handling in C++  An object oriented approach to exception handling  try-catch model of exception handling  Exception handling example  Re-throwing exceptions  Exception specifications Multi-threading Multi-threading  Thread creation  Thread priority  Thread synchronisation

3 Introduction We will look at 2 more advanced topics in C++ We will look at 2 more advanced topics in C++  Exception handling  Multi-threading

4 An object oriented approach to exception handling Robust C++ programs must include exception handling Robust C++ programs must include exception handling Exceptions are error conditions encountered in executing class methods Exceptions are error conditions encountered in executing class methods  Attempting to read past an end of file  Attempting to read a file that doesn’t exist  Trying to open a malformed URL  Divide by zero  Taking the square root of a negative number  etc

5 Normal error handling (in C) would return an error code (eg. –1) Normal error handling (in C) would return an error code (eg. –1) class myClass { public: int readFile(….) { do { if (!end_of_file) // read the file else return –1; } while not_end_of_file return number_of_bytes_read; } };

6 This is a simple sometimes effective method but: This is a simple sometimes effective method but:  Sometimes not possible to return a valid error code.  Not object oriented! No information about the error is contained in the error code  Application code gets ‘polluted’ with error checking code  It would be nice to have all of the error handling in one place  The method might not be able to return normally from the error.  An example would be if a resource the method was accessing was not available

7 The try-catch model of exception handling Object-oriented applications comprise the use of pre-defined components (objects) by the application and the interaction between these objects Object-oriented applications comprise the use of pre-defined components (objects) by the application and the interaction between these objects  The object cannot know in advance how the application will process any error conditions it encounters  The try-catch mechanism is a means by which errors in object code can be communicated in a consistent way to the calling application

8 Application Object 1 Method call Error condition try clause catch clause

9 Exception handling example We will look at a simple example of exception handling involving handling a simple divide by zero error We will look at a simple example of exception handling involving handling a simple divide by zero error  The exception handler simply prints out an error message  However, the key point is that the program doesn’t terminate but allows the user to continue

10 #include class DivideByZeroException : public exception { public: DivideByZeroException::DivideByZeroException() : exception("Attempted divide by zero") {} }; double quotient(int num, int den) { if (den==0) throw DivideByZeroException(); return (double)(num)/den; }

11 int main() { int number1,number2; double result; cout<<"Enter two integers : "; while (cin >> number1 >> number2) { try { result=quotient(number1,number2); cout << "The quotient is " << result << endl; } catch(DivideByZeroException &dzException) { cout << "Exception! " << dzException.what() << endl; } cout << "\nEnter two integers : "; } return 0; }

12 Key point is the calling of quotient() within the try clause Key point is the calling of quotient() within the try clause  quotient() throws the DivideByZeroException exception using the throw() keyword if a zero denominator is input  This is then caught in the catch clause immediately after the try clause

13 Re-throwing exceptions Often, the exception handler is unable to adequately process the exception Often, the exception handler is unable to adequately process the exception  For example, it might not be appropriate for the exception to be handled within the object in which the exception was generated  Typically, the exception is then re-thrown on to an outer object  It is possible to have chains of unhandled exceptions re-thrown  At some level, the exception must be handled

14 main Object 2 Object 1 throws exception Calls method of re-throw handles exception re-throw

15 class MyClass1 { public: MyClass1() {} void aMethod1() { try { throw exception(); } catch (exception &caughtException) { cout << "Exception thrown in aMethod1" << endl; throw; } };

16 class MyClass2 { public: MyClass2() {} void aMethod2() { MyClass1 myObject1; try { myObject1.aMethod1(); } catch(exception &caughtException) { cout << "Exception re-thrown in aMethod2" << endl; throw; } };

17 int main() { MyClass2 myObject2; try { myObject2.aMethod2(); } catch(exception &caughtException) { cout << "Exception handled in main" << endl; } cout << “Program terminates "; return 0; }

18 In this simple example, an exception in generated in one object, re-thrown in the handler of the calling object and then handled in the main program In this simple example, an exception in generated in one object, re-thrown in the handler of the calling object and then handled in the main program  The program produces the following output: Exception thrown in aMethod1 Exception re-thrown in aMethod2 Exception handled in main Program terminates

19 Exception specifications An exception specification (a throw list) enumerates a list of exceptions that a function can throw An exception specification (a throw list) enumerates a list of exceptions that a function can throw Indicates that the function throws exceptions only of types ExceptionA, ExceptionB, ExceptionC Indicates that the function throws exceptions only of types ExceptionA, ExceptionB, ExceptionC  If it throws a different type of exception, then function unexpected() is called which normally aborts the program int aFunction(int arg) throw (ExceptionA, ExceptionB, ExceptionC) { // function body)

20 (No exception specification.) Indicates that the function can throw any exception (No exception specification.) Indicates that the function can throw any exception (Empty specification.) Indicates that the function cannot throw an exception (Empty specification.) Indicates that the function cannot throw an exception  If it does, function unexpected() is called int aFunction(int arg) { // function body) int aFunction(int arg) throw() { // function body)

21 Comparison with Java Comparison with Java  Exception handling almost identical in Java and C++ with a few minor syntactic differences  The main difference is a member function must advertise when it throws an exception in Java  This function must then be called in a try-catch clause int aFunction(int arg) throws IOException // Java { // function body)

22 Multi-threading in C++ We are familiar with the idea of multi-tasking We are familiar with the idea of multi-tasking Multi-tasking refers to an operating system running several processes concurrently Multi-tasking refers to an operating system running several processes concurrently  Each process has its own completely independent data  Multi-tasking is difficult to incorporate in application programs requiring system programming primitives

23 However, a single application program can be written as a set of threads which run concurrently (in parallel) However, a single application program can be written as a set of threads which run concurrently (in parallel) A thread is different from a process in that threads share the same data A thread is different from a process in that threads share the same data  Switching between threads involves much less overhead than switching between programs  Sharing data can lead to programming complications (for example in reading/writing databases)

24 C++ has direct access to low level API thread functions C++ has direct access to low level API thread functions  In contrast to Java and C# which has an extra processing layer (within the Thread class)  It’s ultimately the OS which provides a multithreading capability  C++ therefore more suited to real-time multi-threading applications

25 The chief advantage of writing multi- threaded code is efficiency The chief advantage of writing multi- threaded code is efficiency  Better use is made of the idle time common in all applications  Waiting for network connections  Waiting for keyboard input  Writing to disk drives  etc  A well written application can execute another task during this idle time

26 A simple C++ Thread class A simple Thread class can easily be developed enabling multi-threaded application to be written A simple Thread class can easily be developed enabling multi-threaded application to be written  Similar in use to the Java Thread class  Makes use of Windows Thread functions

27 class Thread { private: string m_strName; public: Thread(); Thread(const char* nm); virtual ~Thread(); void setName(const char* nm); string getName() const; void start(); virtual void run(); void sleep(long ms); void suspend(); void resume(); void stop(); void setPriority(int p); bool wait(const char* m,long ms=5000); void release(const char* m); // Thread priorities static const int P_HIGHEST; static const int P_LOWEST; static const int P_NORMAL; }

28 As in the case of Java, we must override the virtual run() method for code to execute in a separate thread. As in the case of Java, we must override the virtual run() method for code to execute in a separate thread. Method start() creates a new thread using the windows function CreateThread() and calls the run() method Method start() creates a new thread using the windows function CreateThread() and calls the run() method Method stop() terminates a thread Method stop() terminates a thread Methods wait() and release() are for thread synchronisation (see later) Methods wait() and release() are for thread synchronisation (see later)

29 Creating a simple multi-threaded application Class MyThread is a derived class of Thread Class MyThread is a derived class of Thread  The run() method simply increments a count  Individual threads are identified by a name which is a string passed to the contsructor  A main() program creates 2 threads with 2 different names

30 #include using namespace std; #include "ou_thread.h" using namespace openutils; class MyThread : public Thread { private: int m_nCount; public: MyThread(int n,const char* nm) { Thread::setName(nm); m_nCount=n; } void run() { for (int i=0; i<m_nCount; i++) { cout << getName().c_str() << ":" << i << endl; } };

31 #include "MyThread.h" int main() { Thread *t1=new MyThread(15,"Thread 01"); Thread *t2=new MyThread(10,"Thread 02"); try { // Start threads t1->start(); t2->start(); t1->stop(); t2->stop(); } catch(ThreadException ex) { cout << ex.getMessage().c_str(); } delete t1; delete t2; return 0; }

32 Program output: Program output:

33 Thread synchronization Each thread pre-empting the other perhaps before a complete line of output is produced Each thread pre-empting the other perhaps before a complete line of output is produced  Produces a confusing result  Even more serious if the threads are accessing a critical resource such as a database or network connection Threads can be synchronized using synchronization objects which allow threads mutually exclusive access to a resource Threads can be synchronized using synchronization objects which allow threads mutually exclusive access to a resource

34 Unsynchronised threads Thread 1Thread 2 Update database Read database Pre-empt

35 Synchronised threads Thread 1Thread 2 Update database Read database

36 Windows supports various methods of synchronising multi-threaded code Windows supports various methods of synchronising multi-threaded code  Semaphores  Event objects  Mutex objects Mutex objects allow one and only one thread to access a mutex object at any one time Mutex objects allow one and only one thread to access a mutex object at any one time  A mutex object is a particular kind of semaphore

37 The Windows function CreateMutex() is called to create the mutex object The Windows function CreateMutex() is called to create the mutex object  Called from the Mutex class constructor In the run() method of MyThread, we must wait for the mutex object to be released by another thread In the run() method of MyThread, we must wait for the mutex object to be released by another thread Must remember to release the object once the run() method terminates Must remember to release the object once the run() method terminates All other methods in MyThread are the same All other methods in MyThread are the same

38 void MyThread::run() { wait("MyMutex"); for (int i=0; i<m_nCount; i++) { cout << getName().c_str() << ":" << i << endl; } release("MyMutex"); }

39 int main() { Thread *t1=new MyThread(15,"Thread 01"); Thread *t2=new MyThread(10,"Thread 02"); try { Mutex m("MyMutex"); t1->start(); t2->start(); t1->stop(); t2->stop(); m.release(); } catch(ThreadException ex) { cout << ex.getMessage().c_str(); } delete t1; delete t2; return 0; }

40 Program output: Program output:

41 The second thread waits until the first thread is finished The second thread waits until the first thread is finished Important to call stop() on all threads in the same order start() was called Important to call stop() on all threads in the same order start() was called The release() function of the Mutex class must be called after the calls to stop() The release() function of the Mutex class must be called after the calls to stop()

42 Thread priority Windows uses the priority level of a thread to determine how is allocates slices of CPU time Windows uses the priority level of a thread to determine how is allocates slices of CPU time Threads have a base priority level by default Threads have a base priority level by default  The priority can be set with the Thread::setPriority() method Threads are scheduled in a round robin fashion at each priority level Threads are scheduled in a round robin fashion at each priority level  Only when there are no executable threads at a higher priority level does scheduling at lower priorities take place

43 int main() { Thread *t1=new MyThread(15,"Thread 01"); Thread *t2=new MyThread(10,"Thread 02"); try { t1->start(); t1->setPriority(Thread::P_LOWEST); t2->start(); t2->setPriority(Thread::P_HIGHEST); t1->stop(); t2->stop(); } catch(ThreadException ex) { cout << ex.getMessage().c_str(); } delete t1; delete t2; return 0; }

44 Program output Program output

45 And finally….. We have looked at exception handling and multi- threading in C++ programming We have looked at exception handling and multi- threading in C++ programming Exception handling is a crucial feature of writing robust error tolerant code Exception handling is a crucial feature of writing robust error tolerant code Its especially important in object oriented programming as exceptions can be passed up the method calling chain and handled by the appropriate object Its especially important in object oriented programming as exceptions can be passed up the method calling chain and handled by the appropriate object Also, in graphical/event handling programs, control is easily passed back to the event handling thread following an exception without causing the program to terminate Also, in graphical/event handling programs, control is easily passed back to the event handling thread following an exception without causing the program to terminate

46 Writing multi-threaded code can be complex Writing multi-threaded code can be complex C++ differs from Java in that there is no in-built Thread class but it is easy to write one using Windows thread functions C++ differs from Java in that there is no in-built Thread class but it is easy to write one using Windows thread functions Multi-threading is the basis of many applications and is particularly crucial in graphical/event driven programming as well as real-time systems which control multiple objects Multi-threading is the basis of many applications and is particularly crucial in graphical/event driven programming as well as real-time systems which control multiple objects A key feature of multi-threaded code is synchronising access to shared resources and C++ has the flexibility to use a range of methods including semaphores A key feature of multi-threaded code is synchronising access to shared resources and C++ has the flexibility to use a range of methods including semaphores


Download ppt "EE4E. C++ Programming Lecture 6 Advanced Topics. Contents Introduction Introduction Exception handling in C++ Exception handling in C++  An object oriented."

Similar presentations


Ads by Google