Προχωρημένα Θέματα ΠΡΟΧΩΡΗΜΕΝΑ ΘΕΜΑΤΑ. Γεώργιος Παπαϊωάννου ( )

Σχετικά έγγραφα
ΚΑΤΑΣΚΕΥΑΣΤΕΣ ΑΝΤΙΓΡΑΦΗΣ

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Εισαγωγή σε αντικειμενοστραφή concepts. Και λίγη C#

ΚΑΛΟΥΠΩΜΑΤΑ & ΜΕΤΑΤΡΟΠΕΣ

Προγραμματισμός Υπολογιστών με C++

Προγραμματισμός Υπολογιστών με C++

Υπερφόρτωση τελεστών

Τελεστές ΤΕΛΕΣΤΕΣ. Γεώργιος Παπαϊωάννου ( )

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

Προγραμματισμός Υπολογιστών με C++

Προγραμματισμός Υπολογιστών με C++ Φύλλο Διαγωνίσματος Ακαδημαϊκό εξάμηνο: Χειμερινό

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡ/ΣΜΟΣ C++

Προγραμματισμός Υπολογιστών με C++

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

Προγραμματισμός Ι. Εισαγωγή στην C++ Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

Εισαγωγή στον Προγραμματισμό

Στοιχειώδης προγραμματισμός σε C++

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

Εισαγωγή στον Αντικειμενοστρεφή Προγραμματισμό Διάλεξη #2

Εισαγωγή στον Προγραµµατισµό, Αντώνιος Συµβώνης, ΣΕΜΦΕ, ΕΜΠ,, Slide 6

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

Αναφορές, είκτες και Αλφαριθμητικά

Αντικείμενα στη Java. Παύλος Εφραιμίδης. Java Αντικείμενα στη Java 1

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

HY150a Φροντιστήριο 3 24/11/2017

Οντοκεντρικός Προγραμματισμός

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Οντοκεντρικός Προγραμματισμός

Κλάσεις και Αντικείµενα

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Προγραμματισμός Υπολογιστών με C++

Αντικειμενοστραφής Προγραμματισμός

Προγραμματισμός Ι. Πίνακες, Δείκτες, Αναφορές και Δυναμική Μνήμη. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εαρινό. Ύλη εργαστηρίου, Ασκήσεις Java

Εισαγωγή εκτελέσιμου κώδικα σε διεργασίες

Κλάσεις στη Java. Παύλος Εφραιμίδης. Java Κλάσεις στη Java 1

ΔΕΙΚΤΕΣ ΚΑΙ ΔΙΕΥΘΥΝΣΕΙΣ

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Πίνακες Κλάσεις και Αντικείμενα

Αντικειμενοστρεφής Προγραμματισμός

Αντικείμενα (Objects) στην Java. Αντικείμενα στη Java. Δημιουργία Αντικειμένων. Δηλώσεις Μεταβλητών (2) Ο τελεστής new (1)

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα

ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΜΑΘΗΜΑΤΙΚΩΝ ΙΠΛΩΜΑΤΙΚΗ ΕΡΓΑΣΙΑ

Ορισµός Νήµα (thread) είναι µια ακολουθιακή ροή ελέγχου (δηλ. κάτι που έχει αρχή, ακολουθία εντολών και τέλος) σ ένα

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Constructors, equals, tostring

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Πίνακες Κλάσεις και Αντικείμενα

Εισαγωγή στον Προγραμματισμό

Προγραµµατιστικές Τεχνικές

Κλάσεις στη Java. Στοίβα - Stack. Δήλωση της κλάσης. ΗκλάσηVector της Java. Ηκλάση Stack

Αρχεία & Ρεύματα ΑΡΧΕΙΑ & ΡΕΥΜΑΤΑ. Γεώργιος Παπαϊωάννου ( ) gepap@aueb.gr

Κλάσεις και αντικείμενα #include <iostream.h<

Τι είναι κλάση Κλάση

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ

Περιεχόμενα. Λίγα λόγια για αυτή την έκδοση... 23

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα

Συμβολοσειρές ΣΥΜΒΟΛΟΣΕΙΡΕΣ. Γεώργιος Παπαϊωάννου ( )

ΣΤΟΙΧΕΙΑ ΤΗΣ ΓΛΩΣΣΑΣ C++ Constructors, Destructors, Pointers IO Streams, File Streams

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Μέθοδοι που επιστρέφουν αντικείμενα Deep and Shallow Copies

ΠΛΗΡΟΦΟΡΙΚΗ ΙΙ (JAVA) 11/3/2008

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Αντικείμενα ως ορίσματα

ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡ/ΣΜΟΣ C++

ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ Α.Π.Θ. ΕΡΓΑΣΤΗΡΙΟ C++ ΕΞΑΜΗΝΟ Γ Ακαδηµαϊκό Έτος

Οντοκεντρικός Προγραμματισμός

2 Ορισμός Κλάσεων. Παράδειγμα: Μηχανή για Εισιτήρια. Δομή μιας Κλάσης. Ο Σκελετός της Κλάσης για τη Μηχανή. Ορισμός Πεδίων 4/3/2008

Δομή Προγράμματος C++, Χειρισμός Μεταβλητών και Συναρτήσεις Εισόδου - Εξόδου

Διάλεξη Εισαγωγή στη Java, Μέρος Γ

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Constructors

ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Δημιουργία Κλάσεων και Αντικειμένων

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Μέθοδοι

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Υπερφόρτωση Αντικείμενα σαν ορίσματα

Συναρτήσεις και Πίνακες

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Μαθήματα από τα εργαστήρια

lab13grades Άσκηση 2 -Σωστά απελευθερώνετε ολόκληρη τη λίστα και την κεφαλή

12. ΑΛΦΑΡΙΘΜΗΤΙΚΑ. υο είδη αλφαριθµητικών Τα αλφαριθµητικά της C πίνακες τύπου char Ta αντικείµενα της κλάσης string

Απάντηση. // We write in a header file named my_header.h #ifndef my_header_h #define my_header_h #define divides(x,y) (((y)%(x)==0)?

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

3 Αλληλεπίδραση Αντικειμένων

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Copy Constructor Deep and Shallow Copies

Οντοκεντρικός Προγραμματισμός

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

Δομημένος Προγραμματισμός (ΤΛ1006)

Εργαστήριο 02: Προγραμματισμός με Γενικούς Τύπους (JAVA Generics) ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι

17TimeThis.h function returns reference pointer to same object { return *this; }

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Στατικές μέθοδοι και μεταβλητές Εσωτερικές κλάσεις

Boost - Boost Graph Library C++ library

Πληροφορική 2. Γλώσσες Προγραμματισμού

ΣΤΟΙΧΕΙΑ ΤΗΣ ΓΛΩΣΣΑΣ C++ Πέρασμα παραμέτρων, συναρτήσεις δόμησης και αποδόμησης

Η βασική συνάρτηση προγράμματος main()

Προγραμματισμός Υπολογιστών με C++

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Δημιουργώντας δικές μας Κλάσεις και Αντικείμενα

Εντολές εισόδου - εξόδου. Εισαγωγή στη C++

Κατανεμημένα Συστήματα

Δομές Δεδομένων & Αλγόριθμοι

Transcript:

ΠΡΟΧΩΡΗΜΕΝΑ ΘΕΜΑΤΑ Γεώργιος Παπαϊωάννου (2015-16) gepap@aueb.gr

Περιγραφή: Shared Pointers Νήματα Αποκλειστική πρόσβαση σε πόρους (Mutexes) Move assignment Ο τύπος «συνάρτηση» Lambda functions Τελευταία ενημέρωση: Δεκ 2015 Εισαγωγή - 2

Υλοποιούν τη λειτουργικότητα ενός pointer που κρατά reference counting και αυτόματα διαγράφει τον εαυτό του όταν: Μηδενιστούν οι αναφορές σε αυτόν Ρητά διαγραφεί Εξ αρχής κατασκευή shared pointer shared_ptr<myclass> p = make_shared<myclass>(); shared_ptr<myclass> p_i = shared_ptr< MyClass >(new MyClass [100]); Copy constructor από κανονικό pointer 3

Οι shared pointers δουλεύουν όπως οι αναφορές στη Java Μόνο που αντί τη διαγραφή τους να την αναλαμβάνει κάποιος garbage collector, εδώ το κάθε στιγμιότυπο αμέσως διαγράφει τη μνήμη του αν μηδενιστούν οι αναφορές σε αυτό (*) Δε χρειάζονται delete Είναι πιο αργοί στη χρήση σε σχέση με τους συμβατικούς pointers (*) Ανάλογα με τον allocator που χρησιμοποιείται. Στην ουσία, μπορούμε να υλοποιήσουμε ολόκληρο gc σύστημα από πίσω μόνοι μας 4

#include <memory> #include <iostream> #include <string> using namespace std; shared_ptr<string> CreatePointer() { return make_shared<string>("foo"); void main() { shared_ptr<string> p_s = CreatePointer(); cout << *p_s << '\n'; cout << "ref. count: " << p_s.use_count() << '\n'; // τυπώνει ref. count: 1 shared_ptr<string> p2 = p_s; cout << "ref. count: " << p_s.use_count() << '\n'; // τυπώνει ref. count: 2 getchar(); 5

Χρήσιμος σύνδεσμος: http://www.cprogramming.com/c++11/rvalue-references-and-movesemantics-in-c++11.html Μια Lvalue είναι μια μη προσωρινή μεταβλητή στην οποία αναθέτουμε ένα προσωρινό αποτέλεσμα, το Rvalue Τη διεύθυνση μιας Lvalue μπορούμε να τη διαβάσουμε και να τη χρησιμοποιήσουμε, ενώ μιας Rvalue χάνεται Μπορούμε να το σκεφτούμε ως το αριστερό και δεξιό τελεστέο μιας εξίσωσης: a = b a: Lvalue, b: Rvalue 6

Πολύ συχνά, κατά τις αναθέσεις, τα Rvalues είναι αναφορές σε προσωρινά αντικείμενα Τα αντικείμενα αυτά χάνονται μετά την «κατανάλωσή» τους string getname (){ return "Alex"; string name = getname(); Επιστροφή προσωρινού αντικειμένου: Rvalue reference Αντιγραφή αντικειμένου (εδώ με ctor) 7

Κανονικά δε μπορούμε να αναθέσουμε προσωρινά δεδομένα σε μια αναφορά string & name = getname(); // Σφάλμα! Στη C++ 11, ορίζεται ένας νέος τύπος αναφοράς, η Rvalue reference που μας επιτρέπει να το κάνουμε string && name = getname(); Μας βοηθάει να προσδιορίζουμε ρητά (κυρίως σε ορίσματα συναρτήσεων) ότι ένα δεδομένο είναι προσωρινό 8

Κατά την αντιγραφή μεγάλων αντικειμένων όπου απαιτείται deep copy, ο copy constructor και copy assignment operator πρέπει να: Δεσμεύσουν μνήμη Να αντιγράψουν δεδομένα Να αποδεσμεύσουν παλιά μνήμη (copy assignment) Αν γνωρίζουμε ότι η Rvalue είναι προσωρινή, μπορούμε απλά να της «κλέψουμε» τους πόρους και να γλυτώσουμε δέσμευση μνήμης και αντιγραφή 9

Επιπρόσθετα με τον Copy assignment operator και Copy constructor, μπορούμε να έχουμε και Move εκδόσεις τους Παίρνουν τα δεδομένα από το όρισμα αντί να τα αντιγράφουν Η επιλογή εξαρτάται από το αν το όρισμα είναι Rvalue reference ή όχι 10

class ArrayWrapper { private: int *_p_vals; int _size; public: // copy constructor ArrayWrapper (const ArrayWrapper& other) : _p_vals( new int[ other._size ] ), _size( other._size ) { for ( int i = 0; i < _size; ++i ) { _p_vals[ i ] = other._p_vals[ i ]; ~ArrayWrapper () { if (_p_vals) delete [] _p_vals; ; Δέσμευση μνήμης Αντιγραφή δεδομένων 11

class ArrayWrapper { private: int *_p_vals; int _size; public:... // move constructor ArrayWrapper (ArrayWrapper&& other) : _p_vals( other._p_vals ), _size( other._size ) { other._p_vals = NULL; other._size = 0; ; ~ArrayWrapper () { if (_p_vals) delete [] _p_vals; Συνυπάρχει με τον copy constructor και επιλέγεται όταν το όρισμα είναι προσωρινή μεταβλητή Κλέβει τον pointer του ορίσματος Ο μηδενισμός του Pointer του ορίσματος μας προφυλάσσει από εσφαλμένη διαγραφή του στο αντικείμενο other 12

Αντί να αντιγράφει το δεξί μέλος στη μεταβλητή ανάθεσης, «κλέβει» τους πόρους από το δεξί μέλος Ισχύει για κλάσεις, δομές και unions struct A { string s; A() : s("test") { A& operator=(a&& other){ s = move(other.s); return *this; ; Δήλωση MOVE assignment Ρητή κλήση του MOVE operator, αν υπάρχει Αναγκαστική μετατροπή (cast) σε Rvalue reference 13

struct A { ; string s; A() : s("test") { A& operator=(a&& other){ s = move(other.s); return *this; void main() { A f; A g; f = A(); f = g; Επιλογή του MOVE = operator από τον compiler. To A() είναι προσωρινό αντικείμενο. Επιλογή του COPY = operator από τον compiler. To g έχει λόγο να συνεχίσει να υπάρχει. 14

Τα νήματα αποτελούν μια εύκολη και γρήγορη μορφή εκτέλεσης κώδικα παράλληλα, μέσα στην ίδια τη διαδικασία της εφαρμογής Ξεκινάνε γρήγορα Χρησιμοποιούν την κοινή περιοχή μνήμης της διεργασίας που τρέχει η εφαρμογή Παρέχουν εύκολους μηχανισμούς ελέγχου και συγχρονισμού Διεργασία (process) Νήματα (threads) Ταυτόχρονα 15

Υλοποιούνται με την κλάση thread (header: <thread>) Ένα thread υποχρεωτικά το αρχικοποιούμε με μια συνάρτηση την οποία θα εκτελέσει Η συνάρτηση αυτή καθορίζει τη «ζωή» του thread Όταν τελειώσει, «κλείνει» το thread 16

void Foo(int a) { long b = a; for (int i = 0; i < 100; i++) cout << (b*=a); Κατασκευαστής void main() { std::thread th = std::thread(foo, 2); Όνομα συνάρτησης που θα τρέξει Ορίσματα της συνάρτησης που θα τρέξει 17

void Foo(int a) { long b = a; for (int i = 0; i < 100; i++) cout << (b*=a); Προκαθορισμένος κατασκευαστής void main() { thread th; th = thread(foo, 2); Move assignment: To προσωρινό αντικείμενο (δεξιά του =), ακυρώνεται μετά την ανάθεση Οποιασήποτε άλλη ανάθεση δε θα είχε νόημα. Διαφορετικά τι θα παρίστανε το προσωρινό αντικείμενο τύπου thread??! 18

Είδαμε πώς να ξεκινάμε νήματα. Πώς τα συγχρονίζουμε όμως; Πρέπει να έχουν ένα συγκεκριμένο σημείο συνάντησης, όπου η συνάρτηση που ξεκινάει ένα thread, περιμένει το (τα) thread(s) να ολοκληρώσει τη δουλειά του Αυτός είναι ο ρόλος της μεθόδου join 19

void EstimatePI(double * res, long iterations); void main() { Ξεκινάμε ένα thread να τρέξει την EstimatePI double result[2]; thread t = thread(estimatepi, result, 1000); EstimatePI(result + 1, 1000); t.join(); Τρέχουμε την EstimatePI στο υπάρχον thread double final = (result[0] + result[1]) / 2.0; Δεν ξέρουμε τι θα τερματίσει πρώτο. Γι αυτό πρέπει να βάλουμε ένα σημείο συνάντησης εδώ πριν χρησιμοποιήσουμε τα αποτελέσματα και από τους 2 υπολογισμούς 20

Ένας τρόπος να υπολογίσουμε την τιμή του π είναι με τη μέθοδο του dart throwing: Παίρνουμε τυχαία και ομοιόμορφα δείγματα σε ένα τετράγωνο πλευράς 1 Η καταμέτρηση όσων πέφτουν μέσα στην ακτίνα (1) του κύκλου μας δίνει το ¼ του ολοκληρώματος του εμβαδού Α και επομένως του π = 4Α/r 2 A = hit / total r Βλ. Σχετικό Παράδειγμα Κώδικα 21

Μπορώ να καλέσω μια μέθοδο ως καλούμενη συνάρτηση ενός thread; Κανονικά όχι, εκτός και αν η μέθοδος είναι στατική Η γλώσσα όμως (C++11), μας επιτρέπει να δούμε μια μέθοδο ενός υπαρκτού στιγμιότυπου ως συνάρτηση με τη συνάρτηση μετατροπής bind 22

#include <iostream> #include <functional> struct int_holder { ; int value; int triple() { return value*3; int main () { int_holder five {5; std::function<int()> triple = std::bind (&int_holder::triple, five); cout << triple(); thread th = thread (triple); Αντικείμενο περίβλημα (wrapper) για συναρτήσεις. Οτιδήποτε μπορεί κάποια στιγμή να κληθεί, μπορεί να μετατραπεί σε αυτόν τον τύπο. Διεύθυνση στην οποία βρίσκεται η αρχή της υλοποίησης της μεθόδου 23

Τα νήματα έχουν πρόσβαση σε κοινούς πόρους, όπως αρχεία, μνήμη κλπ Αν τα νήματα κάνουν υπολογισμούς πάνω σε δεδομένα που τα άλλα νήματα τροποποιούν, θα προκύψουν λάθη Πολλές φορές χρειάζονται επομένως αποκλειστική πρόσβαση σε πόρους 24

Είναι ένας μηχανισμός που επιτρέπει σε ένα νήμα να μπει σε ένα τμήμα κώδικα που εγκυμονεί προβλήματα (critical section) και να εξασφαλίσει την αποκλειστική χρήση των πόρων Τα υπόλοιπα νήματα (με δική μας εντολή): Είτε περιμένουν να πάρουν σειρά Είτε εγκαταλείπουν την προσπάθεια (return) Non-critical section Wait to lock Mutex Critical section Unlock Non-critical section 25

#include <thread> #include <mutex> using namespace std; mutex m; void ThreadFunction() { // Non-critical section... // Critical section m.lock();... m.unlock(); // Exit critical section // Non-critical section... void main() { thread t1 = thread(threadfunction); thread t2 = thread(threadfunction); t1.join(); t2.join(); Βλ. Σχετικό Παράδειγμα Κώδικα 26

Η C++ μας παρέχει έτοιμες λειτουργίες ή λειτουργίες για να εφαρμόσουμε μαζικά αλγορίθμους πάνω σε συλλογές Βρίσκονται στο header algorithm Π.χ.: sort και binary_search for_each find_if, any_of, none_of, count, count_if generate 27

bool negative(int n) { return n < 0; int main() { std::array<int, 7> foo = { 0, 1, -1, 3, -3, 5, -5 ; if (std::any_of(foo.begin(), foo.end(), negative)) std::cout << Found negative elements.\n"; array: wrapper class για έναν στατικό πίνακα, ώστε να διαθέτει: Α) iterator B) size() μέθοδο 28

int negate(int & n) { return n*-1; int main() { std::array<int, 7> foo = { 0, 1, -1, 3, -3, 5, -5 ; std::transform(foo.begin(), foo.end(), foo.begin(), negate); for (auto o : foo) std::cout << o << " "; 29

Σε όλες τις παραπάνω περιπτώσεις, για να επενεργήσουμε πάνω σε κάποια δεδομένα, χρειαζόταν να δημιουργήσουμε πρώτα μια συνάρτηση ή ένα function object (ή εναλλακτικά ένα αντικείμενο με τον τελεστή () υλοποιημένο) - Callables Πολλές φορές δε θέλουμε να ορίσουμε και δημιουργήσουμε χωριστά ένα Callable αν πρόκειται να χρησιμοποιηθεί μόνο σε ένα σημείο Μπορούμε να κατασκευάσουμε επί τόπου μια ανώνυμη συνάρτηση, ενδεχομένως μαζί με το περιβάλλον της (μεταβλητές ή άλλες συναρτήσεις) Lambda Function 30

[a,b,&c] : Βλέπει τις μεταβλητές a και b κατά τιμή και την c με αναφορά [] : Δε χρησιμοποιεί καμία μεταβλητή του περιβάλλοντος [=] : Όλες τις μεταβλητές του περιβάλλοντος κατά τιμή [&] : Όλες τις μεταβλητές του περιβάλλοντος με αναφορά [ capture-list ] ( params ) -> ret { body Παράμετροι συνάρτησης Τύπος επιστροφής Σώμα συνάρτησης 31

int main() { std::array<int, 7> foo = { 0, 1, -1, 3, -3, 5, -5 ; Ανώνυμη συνάρτηση std::transform(foo.begin(), foo.end(), foo.begin(), [](int x) {return x*=-1; ); for (auto o : foo) std::cout << o << " "; getchar(); [ ]: Προσδιορίζει πώς χρησιμοποιεί η ανώνυμη συνάρτηση τις μεταβλητές του περιβάλλοντος κλήσης. Εδώ δεν τις χρειάζεται -> int Στις περισσότερες περιπτώσεις ο compiler μπορεί να εξάγει τον τύπο επιστροφής χωρίς να τον δώσουμε ρητά 32

int main() { std::vector<int> some_list; const int multiplier = 2; int total = 0; for (int i = 0; i<5; i++) some_list.push_back(i); std::for_each(begin(some_list), end(some_list), [&total, multiplier](int x) {total += x*multiplier; ); std::cout << "total = " << total; getchar(); [ ]: Χρησιμοποιεί την total με αναφορά (την αλλάζει) και την multiplier με αντιγραφή (δεν την αλλάζει) 33

Η C++ μας δίνει τη δυνατότητα να κρύψουμε την έννοια του νήματος Με τη συνάρτηση std::async μπορούμε να ζητήσουμε την ασύγχρονη (και πιθανά παράλληλη) εκτέλεση μίας ή περισσοτέρων διαδικασιών Το αποτέλεσμα μιας ασύγχρονης εκτέλεσης μιας διαδικασίας (task) είναι ένα future Future: μελλοντικό αποτέλεσμα, κάτι που «θα» είναι έτοιμο σε κάποια μεταγενέστερη στιγμή 34

Ένα future ενσωματώνει 2 πράγματα σε ένα περίβλημα: Την τιμή ενός αποτελέσματος όταν αυτό γίνει διαθέσιμο Το μηχανισμό συγχρονισμού για να περιμένει το αποτέλεσμα (ένα join() πρακτικά) 35

template <typename T, typename ΤIter> int parallel_sum(titer beg, TIter end) { auto len = end - beg; if (len < 1000) return std::accumulate(beg, end, 0); TIter mid = beg + len / 2; std::future<t> handle = std::async(std::launch::async, parallel_sum<t, TIter>, mid, end); int sum = parallel_sum<t>(beg, mid); return sum + handle.get(); int main() { std::vector<int> v(10000, 1); std::cout << Sum = " << parallel_sum<int>(v.begin(), v.end()) << '\n'; 36