Presentation is loading. Please wait.

Presentation is loading. Please wait.

CMPE Data Structures and Algorithms in C++ May 10 Class Meeting

Similar presentations


Presentation on theme: "CMPE Data Structures and Algorithms in C++ May 10 Class Meeting"— Presentation transcript:

1 CMPE 180-92 Data Structures and Algorithms in C++ May 10 Class Meeting
Department of Computer Engineering San Jose State University Spring 2018 Instructor: Ron Mak

2 The auto Keyword In a declaration of a variable that is also being initialized, the compiler can infer the type of the variable from the initialization expression. type inference, AKA type determination Use auto instead of a complicated type name. Examples: Instead of: Use: vector<int>::iterator current = a_container.begin(); map<string, DistanceToCity>::iterator p = cities.lower_bound(new_city.get_name()); auto current = a_container.begin(); auto p = cities.lower_bound(new_city.get_name());

3 The decltype Pseudo-Function
Takes a variable as an argument. Returns the type associated with the variable. Create another variable with the same type. Ensure that two variables have the same type. Example: map<string, int>::iterator start_point; decltype(start_point) end_point;

4 Function Definitions in Header Files
If a member function is small, such as a constructor, a getter, or a setter, you can put its definition inside the class declaration. You can have definition code in the header file. Example: Inline1.h class Inline1 { public:     Inline1(int v) : value(v) {}     int  get_value() const      { return value; }     void set_value(const int v) { value = v; } private:     int value; };

5 Function Definitions in Header Files, cont’d
InlineTest1.h #include <iostream> #include "Inline1.h" using namespace std; int main() {     Inline1 it(5);     cout << it.get_value() << endl;     it.set_value(7);     return 0; } Output: 5 7

6 Function Definitions in Header Files, cont’d
When you put a member function definition inside the class declaration, the compiler can inline the function code. Instead of compiling a member function call the usual way, the compiler will instead insert the function code itself in place of the call. This will speed execution (since no calls are executed), but it increase the size of the compiled code.

7 The inline Keyword If you define a member function outside of the class declaration, you can use the inline keyword to ask the compiler to inline the function code. The compiler may ignore the keyword. It’s usually better to let the compiler decide what’s best for code optimization. Put the inlined member function definitions in the header file.

8 The inline Keyword, cont’d
InlineTest2.cpp class Inline2 { public:     Inline2(int v) : value(v) {}     int  get_value() const;     void set_value(const int v); private:     int value; }; inline int  Inline2::get_value() const      { return value; } inline void Inline2::set_value(const int v) { value = v; } This is preferred since it keeps the separation of function declaration and function definition.

9 The inline Keyword, cont’d
You can also inline regular functions, not just member functions: InlineTest3.cpp #include <iostream> using namespace std; inline int adder(const int a, const int b); int main() {     int i = 2, j = 3;     cout << i << " " << j << " " << adder(i, j) << endl;     return 0; } inline int adder(const int a, const int b)     return a + b; 2 3 5

10 Lambda Expressions Person.h #include <string>
using namespace std; enum class Gender { M, F }; class Person { public:     Person(string f, string l, Gender g);     virtual ~Person();     string first;     string last;     Gender gender; };

11 Lambda Expressions, cont’d
Person.cpp #include "Person.h" #include <string> Person::Person(string f, string l, Gender g)     : first(f), last(l), gender(g) { } Person::~Person()

12 Lambda Expressions, cont’d
#include <iostream> #include <vector> #include "Person.h" vector<Person> init(); ostream& operator <<(ostream& outs, Person &p); vector<Person> match(const vector<Person> people, bool f(const Person &p)); bool is_male(const Person &p); bool is_C(const Person &p); int main() {     vector<Person> people = init();     vector<Person> males;     vector<Person> cs;     cout << "Males:" << endl;     males = match(people, is_male);     for (Person& p : males) cout << p << endl;     cout << endl << "Last name starts with C:" << endl;     cs = match(people, is_C);     for (Person& p : cs) cout << p << endl; } PersonTest1.cpp

13 Lambda Expressions, cont’d
PersonTest1.cpp vector<Person> init() {     vector<Person> v;     v.push_back(Person("Ron",    "Mak",     Gender::M));     v.push_back(Person("Marie",  "Curie",   Gender::F));     v.push_back(Person("Agatha", "Cristie", Gender::F));     v.push_back(Person("Barack", "Obama",   Gender::M));     return v; } ostream& operator <<(ostream& outs, Person &p)     outs << "  {" << "first=" << p.first << ", last=" << p.last          << ", gender=" << (p.gender == Gender::F ? "F" : "M") << "}";     return outs; vector<Person> match(const vector<Person> people, bool f(const Person &p))     vector<Person> matches;     for (const Person& p : people) if (f(p)) matches.push_back(p);     return matches;

14 Lambda Expressions, cont’d
bool is_male(const Person &p) {     return p.gender == Gender::M; } bool is_C(const Person &p)     return p.last[0] == 'C'; PersonTest1.cpp Males:   {first=Ron, last=Mak, gender=M}   {first=Barack, last=Obama, gender=M} Last name starts with C:   {first=Marie, last=Curie, gender=F}   {first=Agatha, last=Cristie, gender=F}

15 Lambda Expressions, cont’d
#include <iostream> #include <vector> #include "Person.h" vector<Person> init(); ostream& operator <<(ostream& outs, Person &p); vector<Person> match(const vector<Person> people, bool f(const Person &p)); int main() {     vector<Person> people = init();     vector<Person> males;     vector<Person> cs;     cout << "Males:" << endl;     males = match(people, [] (const Person &p) -> bool                           {                               return p.gender == Gender::M;                           });     for (Person& p : males) cout << p << endl;     cout << endl << "Last name starts with C:" << endl;     cs = match(people, [] (const Person &p) -> bool                        {                            return p.last[0] == 'C';                        });     for (Person& p : cs) cout << p << endl; } PersonTest2.cpp

16 Break

17 Multithreaded Programming
Multithreading is a way for an executing program (called a process) to have multiple simultaneous execution paths (called threads). Because the threads all run within one process, they all share resources such as memory. Multithreading allows a program to distribute work among multiple CPUs (cores) to be done in parallel (concurrently).

18 Multithreaded Programming, cont’d
Most computers today are multicore. A programmer who only knows how to do single-threaded programming will soon be obsolete. However, multithreaded programming is still hard to do correctly. Few programming languages have built-in support for multithreaded programming. Not C , which requires a library to do it.

19 Multithreaded Programming, cont’d
Code, data (memory), and files are shared!

20 Race Condition If multiple threads are simultaneously executing and sharing resources, how can we prevent one thread from “stepping” on another thread? Example: Thread A is setting the value of variable X while Thread B is also setting the value of variable X. A race condition: The value of variable X depends on the order of execution of Thread A and Thread B. It can be random!

21 Critical Region For a shared resource (such as variable X), the statements in a thread that access the shared resource is a critical region of the thread. AKA critical section Each thread’s critical region can be different from the critical region of other threads. They may have different statements. But the statements of each critical region access the shared resource.

22 Critical Regions and Shared Resources
Do not confuse critical region with the shared resource. Two (or more) threads can share a piece of data. The code in a thread that accesses that shared data is that thread’s critical region with respect to that shared data. Another shared resource would be associated with another set of critical regions.

23 Critical Regions and Shared Resources, cont’d
The code in the critical region of each thread can be different from the code in the critical region of another thread. What the code in the critical regions have in common is that they access the same shared piece of data. Another piece of shared data would be associated with another set of critical regions within the threads that access that data.

24 Mutual Exclusion, cont’d
To protect the integrity of a shared resource, we must use the principle of mutual exclusion. If one thread is in its critical section and is writing to the shared resource (such as setting the value of a shared variable), no other thread is allowed in its critical region. No other thread can read or write the shared resource. Each of the other threads must wait to enter its critical section (it’s blocked from entering).

25 Mutual Exclusion, cont’d

26 Mutual Exclusion, cont’d
Multiple threads can be in their critical sections if they are only reading the shared resource (such as getting the value of a shared variable). Since the shared resource is not changing, there is no race condition.

27 To Prevent Race Conditions
Mutual exclusion: No two threads may be simultaneously inside their critical regions modifying the same shared data. Progress: No thread running outside its critical region may block other threads. Bounded waiting: No thread should have to wait forever to enter its critical region.

28 To Prevent Race Conditions, cont’d
When a thread is in its critical region, other threads must be blocked from entering their critical regions. No assumptions may be made about the number of CPUs or their speeds.

29 Sleep and Wakeup A race condition with shared variable count:
void producer() { for (;;) { item = produce_item(); if (count == N) sleep(); insert_item(item); count++; if (count == 1) { wakeup(consumer); } void consumer() { for (;;) { if (count == 0) sleep(); item = remove_item(); count--; if (count == N-1) { wakeup(producer); } consume_item(item); A race condition with shared variable count: The buffer is empty, so the consumer sees count to be 0. Right then, the producer runs, increments count to 1, and tries to wake up the consumer. The consumer is already awake, so the wakeup call is lost. The consumer runs again. It saw count was 0, and so goes to sleep. The producer fills up the buffer and never wakes up the consumer.

30 Semaphores and Mutexes
We need a way to keep track of wakeup calls so that we don’t lose them. A semaphore is a special variable that holds an integer value and has atomic actions: Testing and modifying a semaphore’s value must all be done without interruption. wait(s) { while (s <= 0) block; s--; } signal(s) { s++; } A semaphore often requires hardware support.

31 Semaphores and Mutexes, cont’d
A semaphore that can have any integer value is a counting semaphore. Used to ensure threads that depend on each other will execute in the proper sequence: Statement S2 can only execute after statement S1. A binary semaphore only has the values 0 or 1. Also called a mutex, to implement mutual exclusion: S1; signal(sem); wait(sem); S2; Just “semaphore” means “counting semaphore”. wait(m); // lock // execute critical region signal(m); // unlock Just say “mutex” rather than “binary semaphore”.

32 POSIX Threads The POSIX standard for threads is implemented by the Pthreads package. Actually, the PThreads function names are all in lower case: pthread_create, pthread_exit, pthread_attr_init, etc. Modern Operating Systems, 3rd ed. Andrew Tanenbaum (c) 2008 Prentice-Hall, Inc All rights reserved

33 Example Multithreaded Program
Professor Zemma Fore is extremely popular with her students! During each of her office hours, students line up to visit her in order to get help and advice. Prof. Fore has a small office. Inside, there is room for only one student to visit. Outside her office, there are three chairs for students to sit and wait their turns.

34 Example Multithreaded Program, cont’d
During an office hour: At the start of the hour, Prof. Fore opens her door for office visits. Students arrive at random times. Prof. Fore sees students in the order that they arrive. Each visit with the professor lasts a random time: 1, 2, 3, 4, or 5 minutes.

35 Example Multithreaded Program, cont’d
During an office hour, cont’d: At the end of a visit, the next waiting student (if any) immediately enters Prof. Fore’s office for a visit. Whenever there are no students visiting or waiting, Prof. Fore works on the design of her programming language “ParFore” for her parallel programming course.

36 Example Multithreaded Program, cont’d
Whenever a student arrives: If Prof. Fore is not already meeting with another student, the arriving student can immediately start an office visit. If Prof. Fore is already meeting with another student, the arriving student sits down on an empty chair outside her office to wait. If there are no empty chairs, the student leaves.

37 Example Multithreaded Program, cont’d
At the end of the office hour: If Prof. Fore is not meeting a student, she closes her door and no more students can visit. If she is meeting a student, she allows that visit to complete (which may take her past her closing time) before closing her door. Any students still waiting then leave.

38 Example Multithreaded Program, cont’d
A program to simulate students visiting Prof. Fore during one of her office hours. Design the program such that 1 second real time = 1 minute simulated time. Write the program using the Pthreads library.

39 Example Multithreaded Program, cont’d
The program should print a message with a timestamp as each event occurs. Events: student arrives, student starts office visit, etc. The output should be in a tabular format that shows the state changes of the components of your simulation. Will Prof. Fore ever find time to work on her language ParFore the course?

40 Example Multithreaded Program, cont’d
The program contains a subtle threading bug! Causes a deadlock under certain circumstances. Can you find the error and correct it? Demo


Download ppt "CMPE Data Structures and Algorithms in C++ May 10 Class Meeting"

Similar presentations


Ads by Google